Image source here

Dynamic Pricing Platform (4/5)

Dr. Manoj Kumar Yadav
redbus India Blog
Published in
6 min readMay 11, 2022

--

So far, we have covered following chapters:

Chapter 1: Introduction

Chapter 2: Littlewood’s rule and EMSR

Chapter 3: Technical Architecture

Dynamic pricing continues to help the bus industry in optimizing the pricing strategy and reduce the uncertainty in yields. There have been exciting phases in building the platform. This is a system which continuously takes signals from the market, then feeds them to models and then evaluates the strategies to price the available seats of bus services based on demand. The criterion that were kept in mind for building the platform were following:

  1. Continuous feed processing,
  2. Reasoning behind every price change to be tracked,
  3. No downtime in fare computations,
  4. APIs for Distribution systems,
  5. View of data model for day to day observations,
  6. Interfaces for analysts to define strategies,
  7. Data Pipelines for building models

Apache Storm

Thanks to Apache Storm’s architecture, it had ensured zero downtimes in fare computations. Well, what it can not help with are the application bugs. Its focus is the development and deploying of fault-tolerant distributed stream computations. It provides a framework for hosting applications. It has two models for building applications, first is a “classic Storm” that frames the application as a directed acyclic graph (DAG) called topology. Second is called “Trident”, it works on top of topology, it as primary focus on aggregation and persistence.

One important component of Storm worth mention is “Nimbus”. At first glance, the nimbus would appear to be a single point of the failure like the “JobTracker” or “NameNode” in a traditional Hadoop cluster. When “Nimbus” go down, existing topologies continue to function. It is also a cluster, and if leader node goes down, another node in cluster is picked as leader node without affecting the running topologies.

Easy Rules

The simple, stupid rules engine for Java™ inspired from this statement “You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions.”-Martin Fowler. Below is the sample rule taken from here:

Rule weatherRule = new RuleBuilder()
.name("weather rule")
.description("if it rains then take an umbrella")
.when(facts -> facts.get("rain").equals(true))
.then(facts -> System.out.println("It rains, take an umbrella!"))
.build();

Below are the features of the engine:

  • POJO based development with an annotation programming model
  • Useful abstractions to define business rules and apply them easily with Java
  • The ability to create composite rules from primitive ones
  • The ability to define rules using an Expression Language (Like MVEL, SpEL and JEXL)

Resource Utilization

The servers setup can be understood as a Queuing System. So, it is important to make sure the hardware that are placed serve and act at best of their capacity with enough buffers for sudden surge in load. CPU Utilizations of the Storm workers observed for an hour, a day and a week:

Storm Worker: CPU utilization observed in an hour
CPU utilization observed in a day
CPU utilization observed in a week

What is noticeable here is the near constant CPU utilization of about 30%. In extreme cases it may jump to 60% utilization, which is taken care by FOS. It is recommended to have this CPU profile for constantly running systems, it not only reduces the possibilities of failure due to predictable available resources but also keeps the costs in check. In this particular use-case about 60% CPU is left for handling spikes and sudden load due to changing market conditions. In general it has FOS as 3. Factor of safety (FOS) is usually used in defining the design parameters of physical products. Same, is used here to provision for unknown loads. One can observe that if the load on CPU was not be consistent, then provisioning for excess load would have been less accurate.

j2html

j2html is a simple, fast and fluent HTML5 builder framework. As mentioned on their site “You think template engines are too slow. This index page was rendered 100 000 times in less than a second on an i5–4670. That’s about a thousand times faster than Apache ‘Velocity’ (hah!)”. A sample code will look like this:

import static j2html.TagCreator.*;

public class Main {
public static void main(String[] args) {
body(
h1("Hello, World!"),
img().withSrc("/img/hello.png")
).render();
}
}

This is a huge time saver if you quickly want to have webpage built integrated into your backend servers for quick view and operations. The Dynamic Pricing Platform has fully integrated UI. This eliminates the need to running more servers (nodejs) to serve the purpose.

Rapidoid

As quoted by the git repo “Rapidoid is an extremely fast HTTP server and modern Java web framework / application container, with a strong focus on high productivity and high performance.” Benchmark from Techempower shows this as performance on cloud puts the rapidoid at 6/7 rank out of 100s of frameworks:

As of 11th May 2022

Rapidoid works with j2html and jeasy for strategy definition and simulations. Systems is flexible enough to run the simulations of production data without impacting the actual production. This gives the freedom to experiment with different signals, models and strategies of pricing. As explained in Chapter 2: Littlewood’s rule and EMSR, the process of dynamically pricing for better yield is also heuristics driven. So, it becomes important to have the freedom to try out different models and strategies. Bus domain being so diverse, it always needs different model for different kind of routes and demand days. All these uncertainties do not impact the platform’s core metric.

Architecture Comments

The systems built are completely decoupled, i.e. any of the components can be picked and replaced with a better and more efficient versions. For an instance, Storm can just be replaced with a single consumer application in java or any other language. Similarly, the jeasy rule engine can be replaced with any other rule engine. Models, are already built in python but connected via APIs with the pricing platform, so that can as well be upgraded as needed.

Next Chapter

In the final chapter of the series, the full story will be summarized for quick reads, and some showcase of current state of the platform.

Chapter 1: Introduction

Chapter 2: Littlewood’s rule and EMSR

Chapter 3: Technical Architecture

Chapter 4: Details & Reasoning

Chapter 5: Future Scope

References:

--

--

Dr. Manoj Kumar Yadav
redbus India Blog

Doctor of Business Administration | VP - Engineering at redBus | Data Engineering | ML | Servers | Serverless | Java | Python | Dart | 3D/2D