Trip.com

Trip.com Uses StarRocks to Power High-Concurrency, Low-Cost Queries

Trip.com moved 70% of the real-time scenarios on its lodging BI platform from ClickHouse, which needed caching and a MySQL path for low-permission users, to StarRocks. Average query response is now about 200 ms, and the team maintains one set of data and code instead of two.

200ms

average query response

About 200 ms across the real-time scenarios already on StarRocks (HData lodging BI platform)

1%

of queries over 500 ms

On StarRocks; on ClickHouse, 95% of response times were within 1 s

70%

of real-time scenarios on StarRocks

Share of the platform's real-time data scenarios migrated at the time of writing (2022); the rest are planned

CompanyTrip.com
Use caseReal-time BI dashboards
Previous solutionClickHouse, with MySQL for low-permission queries
Employees3,000+
ReplacedClickHouse and MySQL (real-time scenarios)

About Trip.com

Trip.com is a travel platform that provides booking services for over 1.5 million hotels worldwide. Our big data business intelligence platform, HData, provides data visualization for the company's lodging business line. It presents data through charts so that teams can make decisions quickly and correctly.

ClickHouse could not support high-concurrency queries. Caching and routing low-permission users to MySQL were a temporary fix that left two sets of data and two sets of code to maintain.

Key takeaway · Concurrency was the limit

This article was written by the Trip.com engineering team.

Each team in the lodging department cares about different metrics and has different permissions, so data is presented in many different ways. The site receives about 2,200 UVs and 100,000 PVs every day. The number doubles or even triples during holidays.

Line chart of daily page views in thousands for HData from April 1 to May 31, mostly between about 60,000 and 180,000 a day with regular dips and a peak near 290,000 in early May
Daily page views (thousands)

The challenge

ClickHouse under concurrent load

We started using ClickHouse in 2018, and 90% of our business line has relied heavily on it since then. ClickHouse kept 95% of response times within 1 s.

We now have about 70 billion records and more than 2,000 processes every day. About 15 billion records need to be updated daily. Uncompressed data is 8 TB; compressed data is 1.75 TB.

Pie chart of query response time intervals in milliseconds before StarRocks; 86% of queries fall in the 0–500 ms range
Query length interval distribution (ClickHouse)

However, ClickHouse could not support high-concurrency queries. In most cases CPU consumption is below 30%, but it climbs to a very high level when user queries peak. A single complex, resource-heavy query can fully load the 40-core CPU in a very short time.

CPU utilization chart from 09:30 to 13:00 with several series rising to 40–55% between 11:00 and 12:00
CPU consumption during query peaks

Caching and traffic splitting

Visits peak at 9:00 AM on weekdays. To keep the system stable, we reduced the load on the ClickHouse servers with both active and passive caching. We cache the query results of frequently visited pages. After offline data is updated, we also analyze user behavior and cache the relevant data for users who visited it in the last 5 days. This took over a large share of the queries that used to hit ClickHouse, flattened the peaks of concurrent queries and kept us from adding servers without limit.

Real-time data remained a problem, and it matters most during holidays. During the 2021 New Year holiday, real-time dashboard visits were 10 times higher than usual. On weekdays CPU usage stays under 30%; during the holiday it went above 70%, which put the stability of the servers at risk.

CPU utilization on a weekday from 03:00 to 14:30, mostly under 10% with a maximum of 28.36%
CPU utilization on a weekday
CPU utilization during the holiday from 07:00 to 13:00, with a maximum of 73.27% around 09:00
CPU utilization during the holiday

We throttled high-frequency user queries on the front end and added a cache on the backend. But real-time data cannot be cached for long: 1–2 minutes is the most users accept. The hit rate of the offline cache is usually 50% or higher, while the real-time cache reaches only 10%.

Monitoring dashboard of cache hit rates per service, with values between 0 and 1; service names are blurred
Cache hit rates

We also split traffic on the server. Requests from users with fewer permissions need less data, so based on data analysis we set a threshold: queries from users whose permission number is below 5,000 are served by MySQL instead of ClickHouse, which returns their results faster. Users with more permissions still query ClickHouse.

This fixed the immediate problems but created new ones:

  • Data consistency between ClickHouse and MySQL is hard to guarantee.
  • Hardware cost increases because there are two sets of data.
  • ClickHouse does not support standard SQL syntax, so we have to maintain two different sets of code, which raises maintenance cost.

Choosing a new OLAP engine

We needed a new OLAP solution that would reduce development and maintenance cost, keep query performance, and handle high-concurrency, high-throughput scenarios. We tried engines including Ignite, CrateDB and Apache Kylin. Each had advantages in hardware cost or performance, but considering all aspects, StarRocks was our best choice. We chose it mainly for:

  1. Sub-second latency.
  2. Performance in complex multi-dimensional analysis, such as high-concurrency and multi-table queries.
  3. Elastic scaling. Online business is not affected while servers are added, and the backends rebalance data automatically.
  4. Hot backup for services in the cluster and multi-instance deployment. Node downtime, decommissioning or failures do not affect the overall stability of the cluster.
  5. Support for materialized views and online schema change.
  6. Compatibility with the MySQL protocol and standard SQL syntax.

The solution

Performance test against ClickHouse

Queries on HData mostly span multiple tables. ClickHouse usually performs better on a single node than as a cluster, so we tested ClickHouse on a single node and compared it with StarRocks in three test cases.

We set up a StarRocks cluster on 6 virtual machines: 3 with mixed frontend and backend deployment, and 3 for backends only. Version: StarRocks v1.16.2.

Server configuration of a StarRocks test node: Linux, 25,110 MB memory, 8 logical processors, 64-bit, CentOS 7.6.1810
StarRocks node configuration (v1.16.2)

ClickHouse version 20.8 ran on the following server:

Server configuration of the ClickHouse server: Linux, 134,400 MB memory, 40 logical processors, 64-bit, CentOS 7.4.1708
ClickHouse server configuration (v20.8)

The test tables:

Table nameRows (thousands)
overseahotelbasicinfo65,000
realtimedailyorder1,000
realtimedailyorder_lastweek2,000
hotelbasicinfo75,000
holdroom_monitor_hotel_value3,000
cii_hotel_eidhotel45,000
tensity_masterhotel10,000

Test case 1

Test case 1 SQL side by side: a standard SQL version with JOIN and FULL JOIN (left) and a ClickHouse version with ALL INNER JOIN, ALL FULL JOIN and USING (right), aggregating hotel orders by hour and country
Test case 1
  • StarRocks: 547 ms
  • ClickHouse: 1,814 ms

Test case 2

Test case 2 SQL side by side: summing room-class and hotel metrics from holdroom_monitor_hotel_value joined to hotelbasicinfo and cii_hotel_eidhotel, written with standard JOINs (left) and ClickHouse ALL INNER JOIN ... USING (right)
Test case 2

Test case 3

Test case 3 SQL side by side: computing daily room tensity from Tensity_MasterHotel joined to hotelbasicinfo and cii_hotel_eidhotel, written with standard JOINs (left) and ClickHouse ALL INNER JOIN ... USING (right)
Test case 3
  • StarRocks: 387 ms
  • ClickHouse: 884 ms

In these tests, StarRocks query performance was better than ClickHouse.

Data ingestion and updates

HData has two main types of data: real-time data and T+1 offline data. We import real-time data with Routine Load, mainly relying on the update model. T+1 offline data is imported with Stream Load into the duplicate key model. For T+1 data, ETL and import run on Zeus, a data synchronization platform we developed.

Real-time import runs through QMQ, a message queue developed at Trip.com. The real-time import process before StarRocks:

Diagram: QMQ messages go through deduplication, SOA calls and data cleaning, then are written to both ClickHouse and MySQL
Real-time ingestion before StarRocks

After we integrated StarRocks, the process became:

Diagram: after deduplication, SOA calls and data cleaning, messages are sent to QMQ, mirrored to Kafka, and consumed into StarRocks with Routine Load
Real-time ingestion with StarRocks

Keeping order status correct

One scenario subscribes to order status change messages. We use the order ID as the primary key downstream and merge the data with the StarRocks update model, and only non-cancelled orders are shown externally. After receiving a status message, we also add fields by calling external APIs. Calling the interface once per message would put too much pressure on it, so we do this in batches.

Apache Kafka only guarantees message order within a partition, not globally. If two records for the same order with different statuses land in two different partitions, Routine Load cannot know which one will be processed first. If the "canceled" record is processed first, the order wrongly ends up "active" after the other record is processed, which causes errors in later analysis.

We considered using native Apache Kafka instead of QMQ and using the order ID as the key that decides the partition, but that required extra development at a high cost. We chose a compromise instead. While messages are merged, we also write to a log table in the StarRocks duplicate key model that holds only order IDs, order status and message timestamps. A timer task sorts the records with the same order ID, keeps the one with the latest timestamp, matches the order IDs against the original table and updates the status if necessary. This makes sure that the records from Apache Kafka always end up with the correct status.

Disaster recovery and high availability

Our disaster recovery (DR) requirements are high, and the company runs DR exercises regularly. StarRocks has its own disaster recovery mechanism, and we built a high-availability setup on top of it:

  • Servers are deployed in 2 server rooms and serve traffic split 5:5. Load balancing for the externally facing frontend nodes is set through configuration items that can be changed and take effect in real time.
  • All frontend and backend processes are guarded by a supervisor, so they are restarted automatically if they exit unexpectedly.
  • When a frontend node fails, the surviving followers immediately elect a new leader, but applications do not learn of it right away. A timer task checks the frontend servers regularly; when it detects a failed frontend node, it removes the node immediately and sends an SMS to our developers.
SMS alert reading "Server: ... got exception! Remove from cluster", with server details blurred
Alert when a frontend node is removed
  • When a backend node fails, StarRocks rebalances the replicas automatically without affecting service. A timer task also checks the backend nodes and emails our developers when one fails.
Email alert titled "StarRocks-BE Abnormal" showing Status: OK, Online_backend_num and Total_backend_num, with values blurred
Alert for a backend node failure
  • We also configured alarms on the hardware indicators of each server. If CPU, memory or disk space looks abnormal, developers are notified and start fixing the issue right away.
StarRocksQMQApache KafkaZeus

The results

At the moment, 70% of the real-time data scenarios on our platform are deployed on StarRocks. The average query response time is about 200 ms, and only 1% of queries take more than 500 ms. We only need to maintain one set of data and one set of code, and the cost of human resources and hardware has decreased significantly.

Line chart of average query response time in milliseconds at 5-minute intervals from 10:00 to 18:00, mostly between 70 and 140 ms with one peak near 250 ms
Average response time (ms)
Pie chart of query response time intervals on StarRocks; 99% of queries fall in the 0–500 ms range
Query length interval distribution (StarRocks)

What's next

  • Migrate the remaining real-time scenarios to StarRocks.
  • Migrate the offline scenarios to StarRocks as well, and gradually unify all OLAP analysis scenarios on StarRocks.
  • Improve monitoring of StarRocks to make it more robust.
  • Separate hot and cold data by reading Apache Hive external tables, reducing hardware cost.