共计 5020 个字符,预计需要花费 13 分钟才能阅读完成。
携程是寰球当先的一站式旅行平台,现有员工约 30000 人,公司旗下的平台可面向寰球用户提供一套残缺的旅行产品、服务及差异化的旅行内容。携程大住宿部是国内最大的酒店分销电子商务平台,在寰球领有约 63 万家国内酒店和 70 万家国内酒店。携程大住宿数据智能平台中 70% 的实时数据场景曾经接入 StarRocks,查问响应速度均匀在 200ms 左右,超过 500ms 的慢查问数大幅度缩小,同时人力和硬件老本大大降低。后续会将残余的实时场景和离线场景全副迁入 StarRocks。
“作者:史文俊,
携程大住宿数据智能部资深开发工程师,负责携程大住宿数据智能平台的研发”
平台现状
大住宿数据智能平台(简称 HData)是一个为携程大住宿业务提供数据可视化的平台,简而言之,就是用图表的模式更为直观地展现与解读数据,帮忙业务取得常识和洞察,造成正确的决策,做出疾速决策,少犯错误。在大住宿外部,每个部门关怀的指标侧重点会不同,权限管制也都会不一样,所以数据展现的形式也是多样化。
HData 每天有将近 2200 左右的 UV,10w 左右的 PV 来拜访咱们的零碎,而节假日期间的访问量根本都会翻 2 到 3 倍。
从 2018 年开始应用 ClickHouse 以来,咱们 90% 的业务线都强依赖于 ClickHouse,95% 左右的接口响应时长都在 1s 以内,ClickHouse 强悍的查问性能失去了充分体现。
当初总数据行数大略 700 亿左右,每天有超过 2000 个左右的流程,须要更新的数据行数大略有 150 亿左右。
未压缩前的数据总容量:8T,压缩后的数据总容量:1.75T。
然而 ClickHouse 无奈反对高并发查问的缺点也很显著,当初 CPU 大部分状况下耗费是在 30% 以内,不过当有用户大量查问时 CPU 使用率可能就会被拉的很高。并且如果呈现一个简单的高耗费查问,只靠人工手刷,可能在很短的工夫内就能够把 40C 的 CPU 使用率打满:
工作日的早上 9 点个别会有一波拜访顶峰,为了放弃零碎稳固,咱们采纳被动建设缓存 + 用户被动触发缓存的机制来升高 ClickHouse 服务器的压力。
一方面咱们会将一些高频拜访的页面查问后果进行缓存。另一方面,在离线数据更新实现后,咱们通过剖析用户行为数据,被动给最近 5 天来拜访过相干数据的用户缓存默认条件的数据,升高波峰。
当初的被动缓存 + 被动缓存取代了本来须要从 ClickHouse 上很大一部分的查问量,这样能够防止咱们有限的扩容服务器。同时也能够把因为集中并发的查问拉起来的峰刺打平。
现阶段痛点
在节假日期间,实时数据是关注的重点,以往年劳动节为例,实时看板的访问量要比平时高 10 倍左右。
工作日期间,CPU 使用率个别不会超过 30%。
节假日期间,CPU 使用率一度超过 70%,这对服务器的稳定性造成了很大隐患。
面对这种状况,一方面咱们在前端做了节流来避免用户高频查问,同时在后端也做了缓存,然而实时数据的缓存工夫不能太久,个别 1~2 分钟曾经是用户可承受的极限。通过下图能够发现,离线数据的缓存命中率个别都会比拟高,根本能达到 50% 以上甚至更高,但对于实时数据,命中率则只有 10% 左右:
另一方面,咱们在服务端启用了分流机制:理论利用场景中有一些业务的权限比拟小,对应须要查问的数据量也会比拟小,咱们通过剖析定义出了一个阈值,比方权限数小于 5000 的用户从 MySQL 申请数据,这部分用户即便通过 MySQL 查问速度也很快。让权限大的用户通过 ClickHouse 申请数据,这样能够引流很大一部分用户。
这样做尽管临时解决了眼下的问题,不过新的问题又接踵而至:
- 数据须要双写到 ClickHouse 和 MySQL,无奈保障两边数据的一致性
- 同时存在两套数据,导致硬件成本增加
- ClickHouse 不反对规范 SQL 语法,所以代码也须要保护两套,开发成本减少
针对上述问题的挑战,咱们的指标是寻求一个新的 OLAP 引擎来缩小开发和运维老本,同时还要兼顾查问性能,并在高并发和高吞吐的场景下有较好的适用性。
为此咱们尝试了一些市面上其余引擎,如 Ingite、CrateDB、Kylin 等,每种引擎从硬件老本或性能上都有本人特有的劣势,不过综合到应用场景,最终咱们抉择了 StarRocks。
StarRocks 介绍
- StarRocks 是一个高性能分布式关系型列式数据库,通过 MPP 执行框架,单节点每秒可解决多达 100 亿行数据,同时反对星型模型和雪花模型。
- StarRocks 集群由 FE 和 BE 形成,能够应用 MySQL 客户端拜访 StarRocks 集群。
- FE 接管 MySQL 客户端的连贯,解析并执行 SQL 语句,治理元数据,执行 SQL DDL 命令,用 Catalog 记录库、表、分区,tablet 正本等信息。
- BE 治理 tablet 正本,tablet 是 table 通过分辨别桶造成的子表,采纳列式存储。BE 受 FE 领导,创立或删除子表。
- BE 接管 FE 散发的物理执行打算并指定 BE coordinator 节点,在 BE coordinator 的调度下,与其余 BE worker 独特合作实现执行。
- BE 读本地的列存储引擎,获取数据,通过索引和谓词下沉疾速过滤数据。
咱们抉择 StarRocks 次要基于以下几方面的思考:
- 亚秒级查问延时
- 在高并发查问、多表关联等简单多维分析场景有良好的性能体现
- 反对弹性扩大,扩容不影响线上业务,后盾主动实现数据 rebalance
- 集群中服务有热备,多实例部署,节点的宕机、下线、异样都不会影响集群服务的整体稳定性。
- 反对物化视图和 Online Schema Change
- 兼容 MySQL 协定,反对规范的 SQL 语法
性能测试
HData 上的数据以多表关联为主,ClickHouse 单机性能比集群性能好,因而抉择单机场景比照。上面用 3 个测试用例别离对 StarRocks 和 ClickHouse 进行比照,咱们用 6 台虚构机构建成了一个集群,3 台 FE、BE 混部,3 台 BE,机器配置如下:
软件版本:StarRocks 标准版 1.16.2
ClickHouse 配置如下:
软件版本:ClickHouse 20.8
测试用例 1
- StarRocks 用时: 547ms
- ClickHouse 用时:1814ms
测试用例 2
- StarRocks 用时: 126ms
- ClickHouse 用时:142ms
测试用例 3
- StarRocks 用时: 387ms
- ClickHouse 用时:884ms
能够看到,StarRocks 的查问性能齐全不逊色于 ClickHouse,甚至更快。
数据更新机制
StarRocks 依据摄入数据和理论存储数据之间的映射关系,将数据表的明细表,聚合表和更新表,别离对应有明细模型,聚合模型和更新模型。
- 明细模型:表中存在主键反复的数据行,和摄入数据行一一对应,用户能够召回所摄入的全副历史数据。
- 聚合模型:表中不存在主键反复的数据行, 摄入的主键反复的数据行合并为一行, 这些数据行的指标列通过聚合函数合并, 用户能够召回所摄入的全副历史数据的累积后果, 但无奈召回全副历史数据。
- 更新模型:聚合模型的非凡情景,主键满足唯一性束缚,最近摄入的数据行,替换掉其余主键反复的数据行。相当于在聚合模型中,为数据表的指标列指定的聚合函数为 REPLACE,REPLACE 函数返回一组数据中的最新数据。
StarRocks 零碎提供了 5 种不同的导入形式,以反对不同的数据源(如 HDFS、Kafka、本地文件等),或者按不同的形式(异步或同步)导入数据。
- Broker Load:Broker Load 通过 Broker 过程拜访并读取内部数据源,而后采纳 MySQL 协定向 StarRocks 创立导入作业。实用于源数据在 Broker 过程可拜访的存储系统(如 HDFS)中。
- Spark Load:Spark Load 通过 Spark 资源实现对导入数据的预处理,进步 StarRocks 大数据量的导入性能并且节俭 StarRocks 集群的计算资源。
- Stream Load:Stream Load 是一种同步执行的导入形式,通过 HTTP 协定发送申请将本地文件或数据流导入到 StarRocks 中,并期待零碎返回导入的后果状态,从而判断导入是否胜利。
- Routine Load:Routine Load 提供了一种主动从指定数据源进行数据导入的性能。用户通过 MySQL 协定提交例行导入作业,生成一个常驻线程,不间断的从数据源(如 Kafka)中读取数据并导入到 StarRocks 中。
- Insert Into:相似 MySQL 中的 Insert 语句,能够通过 INSERT INTO tbl SELECT … 或 INSERT INTO tbl VALUES(…)等语句插入数据。
HData 中的数据次要分为实时数据和离线 T + 1 数据。
实时数据次要通过 Routine load 的形式导入,以应用更新模型为主
离线 T + 1 数据次要应用 Zeus 平台,通过 Stream load 的形式导入,以应用明细模型为主
实时数据通过携程自研的音讯队列零碎 QMQ 实现,下图是原先的实时数据导入流程:
接入 StarRocks 后的实时数据导入流程:
很快咱们就遇到了一个难题:有一个场景是订阅订单状态变动的音讯,上游咱们以订单号作为主键,应用更新模型来将数据落地。对外咱们提供订单状态为非勾销的数据进行展现。
在收到音讯后,咱们还须要调用内部接口来补全一些其余字段,最初再把数据落地。但如果收到一条音讯就调用一次接口,这么做会对接口造成压力,所以咱们采取了批处理的形式。
不过这样做产生了一个问题:Kafka 自身无奈保障全局音讯是有序的,只能保障 partition 内的有序性。同一个批次同一个订单,但订单状态不同的 2 条数据如果别离落在了不同的 partition,routine load 时无奈保障哪条数据会先被生产。如果订单状态为勾销的音讯先被生产,而其余订单状态的音讯后被生产,这样会造成本来应该勾销的订单从新变成了非勾销订单,从而影响统计的准确性。
咱们也思考过不通过 QMQ 而改用原生的 Kafka,将订单号作为 key 来指定发送到哪个 partition 中,不过这样做须要二次开发,而且改变的老本也不低。
为了解决这个问题,咱们抉择了一个折中的方法:在音讯落地同时,又用明细模型落地了一个日志表,表里只须要存订单号、订单状态以及音讯发送工夫。同时,有一个定时工作每隔一段时间会对该表内雷同订单号的数据进行排序,取音讯发送工夫最新的一条数据,用订单号与正式表中订单状态不统一的数据进行匹配而后进行更新,以这样的模式对数据进行一个弥补。
T+ 1 数据咱们通过携程自研的数据同步平台 Zeus 进行 ETL 和导入:
DR 和高可用
携程对 DR 有着很高的要求,每隔一段时间都会有公司级的 DR 演练。StarRocks 自身曾经具备了非常优良的 DR 机制,在此基础之上,咱们构建了一套适宜本人的高可用体系:
- 服务器别离部署在 2 个机房,以 5:5 的流量对外提供服务。对外提供服务的 FE 节点的负载平衡以配置项的模式实现,能够动静批改,实时失效(次要是思考有服务器打补丁、版本升级等须要手动拉出的状况)。
- 每个 FE 和 BE 过程全副都用 supervisor 进行过程守护,保障过程出现意外退出时能够被主动拉起。
- 当 FE 节点呈现故障时,存活的 follower 会立刻选举出一个新的 leader 节点提供服务,然而利用端却无奈立刻感知,为了应答这种状况,咱们起了一个定时工作,每隔一段时间对 FE 服务器进行 health check,一旦发现 FE 节点故障,则立刻将故障节点拉出集群,同时以短信形式告诉开发人员。
- 当 BE 节点呈现故障时,StarRocks 外部会主动进行正本平衡,对外仍可持续提供服务,同时咱们也会有一个定时工作对其进行 health check,每当发现有 BE 节点故障,则会以邮件模式告诉开发人员。
同时,咱们针对每台服务器的硬件指标也配置了告警,通过携程自研的智能告警中台,一旦服务器的 CPU、Mem、磁盘空间等指标产生异样,开发人员能够立刻感知并染指。
总结和前期布局
当初 HData 中 70% 的实时数据场景曾经接入 StarRocks,查问响应速度均匀在 200ms 左右,耗时 500ms 以上的查问只占总查问量的 1%;并且数据和代码也只须要保护一套,人力和硬件老本大大降低。
前期布局
- 将残余的实时场景全副迁入 StarRocks。
- 离线场景也逐步迁入 StarRocks,逐渐用 StarRocks 来对立 OLAP 剖析全场景。
- 进一步欠缺对 StarRocks 的监控机制,使其更强壮。
- 通过读取 Hive 表面的模式做数据冷热拆散,缩小硬件老本。