分享嘉宾:王玉 唯品会
编辑整理:刘鹏鹏 滴滴出行
出品平台:DataFunTalk
导读:大家好,我是来自唯品会实时平台 OLAP 团队的王玉,主要负责唯品会这边 Presto、Kylin、ClickHouse、Kudu,这些在 OLAP 比较常用组件的开源修改、组件优化还有维护的工作,并且我们还负责一些为业务指导、设计 OLAP 方案支持的工作。
本文主要介绍唯品会 OLAP 的演进,包括 Presto 智能化和容器化实践,以及 Clickhouse 在实验平台海量数据存储和计算的实践。将具体介绍 Presto 怎么做到集群 HA,以及和其他大数据组件借调资源。还有我们为什么选择 Clickhouse,Clickhouse 使用中有哪些可以优化的点。
将从以下四个方面进行展开:
- OLAP 在唯品会的演进
- Presto 在唯品会的实践
- ClickHouse 的使用
- 唯品会 OLAP 的未来展望
01
OLAP在唯品会的演进
1. OLAP在唯品会的演进
首先分享的是OLAP在唯品会的使用。
① Presto
Presto作为当前唯品会OLAP的主力军,经历了数次的架构和使用方式的进化。目前,共有物理机500多台,每台约64CPU、256G内存,服务于20多个线上业务,日均查询高峰可达500万次,每天处理和读取接近3PB数据。并且我们在Presto上也做了一些工具及源码的修改,后面会详细说一下。
② Kylin
Kylin作为Presto的补充,主要是对一些海量的数据,不太适用于Presto这种实时查询的情况。Presto更适合一些预聚合、定期的固定报表。
③ ClickHouse
ClickHouse作为我们的新贵,现在拥有两个集群,每个集群大概20~30台高配物理机,服务于实验平台、OLAP日志查询、打点监控等项目。并且在今年和明年我们会有一个大范围的使用,排队等着用ClickHouse的业务现在也是比较多的。
2. 唯品会OLAP部署架构模式
接下来我们来看一下唯品会整体的部署架构模式,主体是在右侧中间的引擎层,包括Presto、Kylin和ClickHouse。下面是数据层包括Hadoop和Spark,这里数据从HDFS导入到ClickHouse中,用的是Waterdrop,目前已经发展到了2.0版本,已经比较稳定。新版本的Waterdrop也可以用Flink把数据搬到ClickHouse。Kafka和Flink是实时数仓,将数据写入ClickHouse或者HDFS时候用的。像ClickHouse这边我们有一个上层的开源组件chproxy,我们在chproxy上还有一层haproxy层,做一个HA层,把haproxy暴露给业务层去使用,从而保证高可用。在Presto代理层这层我们则使用自己研发的工具nebula,在整个代理层之上另外提供了一些数据服务。平行于这条链路的左侧,是整个的一套监控链路,我们对每一个从底层到引擎层,到proxy层再到数据服务层都有对应的服务健康度监控。
02
Presto在唯品会的实践
1. Presto自身架构
下面我们来聊一下唯品会在Presto的实践,Presto是FaceBook开源的分布式SQL引擎,适用于交互查询分析,我们可以看一下整个的架构,它主要有一个Coordinator,就是它的Master,在Master上部署了一个Discovery Service,保证下面的Worker当前状态以及有哪些连接了Coordinator。Worker后面有很多的Connector,我们也是用这个特色,可以连很多个Hive、MySQL、Kudu,并且把它们作为一个数据源放到一块去做join之类的聚合及排序操作,我们Presto集群的Catalog都是很多的,有好多套MySQL、Hive还有Kudu,都是直接配置好后给业务方去使用。
2. 业务数据量增长带来的问题
我们Presto用的比较多以后,就发现了很多比较头疼的问题。
- Master单活的问题:Presto自身的Coordinator是一个单活的情况,它挂掉了整个集群就挂掉了,相对来说还是比较脆弱的。
- 冷热查询不均匀的问题:特别是我们的Presto在唯品会有ETL场景,ETL和AD-Hoc我们大家知道是非常不一样的两个场景,我们会在下文提到。
- 查询非持久化:Presto查询自身只保存很短的时间,通过参数配置,存多长时间、存多少条,历史信息也没有地方可以查询。
- 缺少告警机制:Presto对查询的SQL也缺少了一些告警的机制,一些大查询往往是等到把集群查到OOM或者把整个集群网络打满了,然后我们通过隔壁其他的监控才会知道这些信息。这时候的Presto集群已经处于一个非常不健康的情况了。
- 无权限管控:Presto本身并没有做一个很好的权限管控。
这就是我们第一阶段碰到的问题。
3. Presto自研管控工具
我们针对这些问题自研了工具nebula,修改了Presto的Server端和Client端的源码,从Presto暴露的API和系统表里获取到的节点的查询信息,一方面将查询落入MySQL,MySQL会通过第二天的ETL Job落入Hive,这样就把查询弄下来了。
我们的最新实践,是把Presto的查询丢到Kafka里面,有一个Flink job会把这些查询落到ClickHouse里面,另外有一部分也会落到Hive里,这个是5分钟的表,这样就做到了实时的Presto监控,用户可以马上方便地查到他刚才查询的各种信息,这样的话,我们在之后对Presto的历史查询做一些历史分析的时候,也会非常地方便,有很多数据都有据可依。
很多同事在使用Presto的过程中可能都会经常问到的一个问题:Coordinator怎样做HA?
图中可以看到我们其实是在整个产品Client的连接下有好多套Presto集群,图中就是A、B、C、D四套,其实我们还有很多套,我们会给这些集群划一个Group,比如三个Presto集群是一个Group,基于它之上会有一个Spider,通过Redis和ZooKeeper能获取它的一些健康度或者查询量的一些信息,来给集群打一个高低分。然后我们在Client端,会在Zookeeper里去看我所属的这个Group的Presto集群,哪一个Presto集群的得分最高、最空闲,就把查询打到这个Presto集群上面去。这样可以玩的事情就非常多了,我们可以通过这样部署把某一个要升级的集群分置为0,这样查询就不会往上面打,我们就可以在用户无感的情况下,做很多如负载均衡、HA之类的事情。随后我们针对于整个链路做了一个全局的全链路监控,下到HDFS的DataNode、NameNode,还有Hive Metastore、Server等的监控,上到我们查询这边Client端的打点信息的监控都在里面。
4. 自研工具解决的问题
这里主要展示我们这些工具带来了哪些功能。随着修改那些源码,解决了负载均衡、蓝绿部署、SQL追溯这样的一些功能。我们也修改了一些源码兼容Hive的权限,所以我们现在Presto跟Hive保持了同权限,在元数据平台里,申请一次权限就可以同步获得所有的权限。
5. 多种类业务带来的问题
我们把这个工具开发出来了以后,又相安无事地过了一年多,其他人觉得Presto用的确实比较爽,他们很多东西不用关心,集群也比较稳定,就越来越多的业务开始用。现在已经发展到二三十个以上的业务在用我们的Presto集群,因此就有了接下来的一些问题。
- 配置的算力不平衡
- 应对突然暴增的流量:大促的时候这么多集群我们怎么去分配。
- 用户配置不透明:用户会在Client配置信息,以前是有一个IP的信息,部署和升级成本比较高,来一个新业务,我们给他加个集群,自己还要找物理机,在物理机去申请去部署这些包,去调试。
- 动态借调:我们现在因为Presto集群500台高配物理机,确实也比较大,夜间AD-Hoc的时候这些机器有很多都是浪费的,所以我们给离线做了一个动态借调,这些都是当时业务给我们提出来的一些难题。
6. Presto容器化
我们针对这些难题,所做的对策就是在19年,把我们所有的500多台物理机上云,上到k8s去做部署,图中可以看到,每个集群都是100Worker、40CPU、110G内存。我们刚才说我们是256G的物理机,这样的话其实就是一台物理机上面有两个worker,然后这两个worker的话,我们是用反亲和性让它不在一个Presto集群上。通过修改源码和k8s上的一些接口对接,把我们Presto里面所有非配置部署的部分抽成一个镜像打包,把所有的配置全部放到HDFS上面,或者以后我们可能会放到云存储上面,这样的话去拉取一个集群,其实只要在HDFS上根据这个Presto集群的名称去拉取对应的配置,然后根据自己的镜像的解压,来生成一个新的集群。我们现在按照在k8s页面上去部署拉取一个新集群的话,大概也就两三分钟左右。然后也可以在这个集群上面用k8s的管理页面,扩容、缩容都可以在上面去进行。我们那些二十多个业务也是用刚才提到的Spider和nebula工具,他们对应那些工具,对底层这些Presto的集群是完全无感的,他们不知道他们是跑在奔驰上还是迈巴赫上,反正都是跑在Presto上面,我们能保证他跑在一个相对于空闲的而且比较适合他的一个集群上就可以了。
7. Presto容器化带来的提升
通过上云改造,我们完成了跟离线团队的多台物理机的借调,白天用于Presto业务的AD-Hoc,夜间就借调出去给离线团队去跑Spark的任务,这样两三百台的256G的物理机夜间是能解决很大一部分离线这边的问题的,也为离线那边省了一大批机器。
其次我们现在部署新的Presto集群扩/缩容的话也是非常的方便,一键就可以去做这些功能,然后由于我刚才说的那些k8s和网络的一些亲和性和反亲和性,我们也让Worker尽可能均匀分布,这样的话也可以让物理机本身更充实,CPU监控的非常漂亮,不会有什么太满或者是太空这样的情况发生。
以上这些就是我们在Presto上去改造的一些东西。
03
ClickHouse的使用
1. ClickHouse的引入
随着业务对OLAP的要求越来越高,在部分业务场景Presto和Kylin无法满足现在的要求。比如我们有一个实验平台,想要一个百亿的日志型的数据去join一个低延迟的打点类型数据来做实验平台的ABTest的分析,中等的QPS、查询响应时间要求在1秒左右。这样的情况下用Presto是很难去实现的,因为presto我们也知道它PushDown是按照分区去释放,一次捞这么多数据的话,内存非常吃力,集群可能就因为这一个查询导致查询非常慢。用Presto去硬查,效率会非常慢,达不到响应SLA的要求。
数据存储方面,ClickHouse主要是一个元数据存储在ZooKeeper,数据按照策略存储在本地的文件路径上面,在部分的特定查询场景上,查询速度甚至是Presto的十倍以上。我们也对ClickHouse做了一些深度的了解,特别是它的向量化引擎和SIMD。通过向量化引擎和SIMD这种批量向量进行数据的一些底层跟机器的直接交互,确实能带来十分快的提升。
2. ClickHouse的优势
ClickHouse有以下两方面的优势:
- 大宽表查询性能优异,其主要分析都是大宽表的SQL聚合。ClickHouse的整个聚合耗时都非常小、性能好,并且具有量级提升。因为是列式存储,也适用于向量化SIMD这些引以为傲的功能。可能分布式做的不是很好,但是在单表或者是这些极致查询上面做的确实非常极致,我们看CK的源码很多东西是能用SIMD的浮点的数字类型的都用了,有些不能用底层这些SIMD的比如字符串,也是将其拆开按照16位16位这样去做,确实是一个极致的底层查询模式的引擎的优化。
- 单表性能分析以及分区对其的join计算都能取得很好的性能优势。比如百亿数量级join几十亿数量级的大表关联大表的场景,在24C 128G * 10 shard(2副本)通过优化取得了10s左右的查询性能。我们是用了主键id按照一定规则去hash然后做分桶,去达到这样的一个查询性能。当然它本身的分布式的join实现的是比较差的,后面我也会说一下。
3. ClickHouse场景-实验平台
下面是唯品会的一个实验例子,唯品会实验平台是通过配置多维分析和下钻分析,提供海量数据的A/B-test实验效果分析的一体化平台。一个实验是由一股流量(比如用户请求)和在这股流量上进行的相对对比实验的修改组成。实验平台对于海量数据的查询有着低延迟、低响应、超大规模数据(百亿级)的需求。现在A/B-test非常火,任何一个业务,去上到一个真正的业务场景上的时候,都要先做一个小的测试,看看跟以前流量比到底是有正向效果还是有反向效果。
4. 实验平台OLAP业务场景
这是一个典型的从A/B-test日志,到打点、下钻、曝光、点击、加入购物车的生成订单的一个链路,搞电商的朋友对这一套都比较熟悉。我们实现了FlinkSQL、Redis的Collector、支持Redis的Sink、Source尾表关联这样的一些操作,可以很方便地把Kafka的数据写到ClickHouse,跟Redis或者是Hive的一些维表做关联,经过一些简单的处理以后,再去给他丢到ClickHouse里面去。
5. 通过FlinkSQL写入数据
这里说一下,Flink在ClickHouse Collector端做的一些改造,支持写入本地表的相关过程主要分为以下几步:
① 根据库名和表名查ClickHouse自带的系统元数据表,system.tables是它自己的元数据表,获取想要写入表的engine信息,这里也列出了对应的SQL,大家如果感兴趣可以去查一下。
② 解析engine的信息,获取它的集群名、本地表名。
③ 根据集群名,查询数据表system.clusters也是集群的元数据信息,我们可以获取它的分片节点信息和app信息。
④ 最后我们根据shard配置的信息,初始化生成随机shard group里的URL来连接,ClickHouse 连接就建成了,其负责将Flink内部的数据结构RowData添加到batch buffer里面,我们是用bacth批次的方式去写,单条写的话就挂了,batch我们也有一些参数配置在里面,后面会跟大家说一下。
这样一个sink给到ClickHouse的Server端。就是我们修改了以后ClickHouse的一个完整的流程。
时序图如上图所示,是flick connector的一些源码,有兴趣的朋友可以去研究一下。
6. 超大型表JOIN
在实际应用场景,我们发现一些特定场景比如刚才我们说的一个需要拿一天的A/B-test日志去join我们一天的流量情况,如果用两张大分布式表join的话非常不理想,甚至是如果再引入几张维表进行join的话将基本上查不出来。
在这种情况下,我们就用了分桶的概念,首先把左表和右表join的字段建表时就用hash规则。murmurHash3_64的性能和稳定性都比较优秀,所以我们采用的是murmurHash3_64这种规则,来让固定的id落入到固定的物理机上。写入方面,我们是在建表的时候指定如果是在Flink SQL这边去写这样的ClickHouse数据的话,如果写分布式表数据量不大,在建表的时候指定murmurHash3_64字段就可以了。如果像我们刚才说的写本地表的话,需要在Flink这一端写入的策略里面加入murmurHash3_64的策略,把它写出来,然后在我们的写入端去根据id分配好它的物理表,这样从数据写入端就已经开始做一个分桶。查询的话用左表是分布式表,右表是local表,这样达到的效果其实就是我们最终想要的分布式表join分布式表的效果。但是因为分桶了所以每个机器上做的其实都是相对于这些id去做的事情。这个语义解析是ClickHouse自身去帮我们去做了一个sub query里面的解析。
需要注意的地方是我们左表不能写成一个子查询,左表写在子查询的话会在执行计划里面类似于查本地表,这样本地表join本地表的话那肯定是有问题的。你在这台机器a台机器上查的话,给你返回的结果就是这台a机器上的本地表join本地表,并没有把所有的集群里面所有表的本地表join本地表数据最后合并在一起再吐给你。
7. 增量数据场景
说完hash策略我们再看一看增量数据更新的场景,我们这边的数据以前都是像Kudu一样的要做一个去重更新。这样都是流量数据要做的实时的更新,我们就调研了他的几个场景,我们也会用MergeTree去做这样的事情。由于实验平台的场景,我们后来是选用了第一个方案,因为备选方案首先要能实时去重,其次就是对实时响应性要求比较高。我们后来看了一下,整个增量场景如果按照这几个Tree去做的话,其实是它的弱项,强项并不在此,也并不在一个高批量的增量数据的更新。现在业界很多公司在这块用的是物化视图来实现这样的事情,但是物化视图了以后其实只能是一个增量更新,历史订单数据要更新的话,用物化视图也要自己想好这个窗口怎么去做,因为物化视图其实增量更新也是硬算,你要做个物化视图就是每一次来个数据硬算的话那就肯定是扛不住,如果是流量更新的话其实场景有限,这里是给大家提供一个怎么去做这件事情的思路。
8. Flink写入遇到的问题
我们在用Flink写入ClickHouse的时候也遇到了不少问题。大家应该都遇到过像too many parts这样的问题,我们解决方案是:
① 首先把一些参数调整一下,把parts_to_throw根据机器cpu、内存等情况调大到10000。
② 我们在Flink的sink算子这块,把sink的并发度和batch做一些定制,比如我们设置的batch是20万条记录或者是60s,这是针对于谁先到达就谁先发送。
这样的场景就是为了应对数据高峰期和低峰期两种不同场景都要去写,保证时效性。
第二个问题就是数据类型的问题,原因就是ClickHouse建表的时候如果去掉Nullable限制,插入的时候就必须给一个确定的值,否则flush的时候就会失败,影响flink sql job的稳定性。
解决方案:
① ClickHouse建表的时候每个字段加上默认值,或者建表的时候加上Nullable约束(这里不建议加约束,主要是ClickHouse针对他的字段类型做了很多优化,加这样的约束以后,可能就在底层不管是存储还是元数据方面的话其实都是会有一些优化没有用上)。
② Flink sql在处理数据时,加上coalesce空值处理函数。
9. ClickHouse查询优化
接下来我们谈一谈ClickHouse能做查询优化的一些地方。
① 选择适合的merge引擎。包括更新场景或者小量的log日志引擎,根据不同场景都能选到比较合适的一种merge引擎,这个大家可以翻看一下CK的官网,对各个引擎说的都非常的详细。
② 做好分区的分级,一级分区二级分区,不过我们现在不太建议用二级分区,因为它的order by这种索引足够优秀了,最好是在分区数和分区内的parts之间取一个平衡。如果是实时写parts数的话可能前几天的数据会merge 的比较好但是实时(今天)这一天的数据可能parts数太多的话查询起来就会比较慢。
③ 根据SQL数据特性,按照字段order by排序,跟MySQL这边一样要根据查询的SQL想好怎么设计一个order by的字段排序,包括命中数,都是有学问在里面的,就看它的一个分类性和整个分类字段的话到底在这个表里面大概是一个什么样的颗粒度。
④ 表最好都做好生命周期使用TTL,特别是ClickHouse本身支持列TTL,把过量TTL的数据甚至可以导到冷数据,你在store里面去配置热数据和冷数据不同的存储,可以把一些数据按你的TTL要求去放到一些冷数据里面。比如热数据用SSD,冷数据用HHD,ClickHouse都可以去帮你用好。像我们之前自己一些其他的引擎的话,都是自己去写脚本去做这些事情的。
⑤ 索引颗粒度的问题。默认是8192行作为一个block,但是我们发现在bitmap这种场景,一行可能列非常大,是一个二进制的或者是一个bitmap这样的一个生成器的场景。这样我们设置的就要小点,像我们自己内部像人群bitmap的话,我们索引颗粒度设置的是2,就是2行就作为一个查找单元,因为我们行数比较少,但是列里面的value值比较大。
10. ClickHouse参数优化
我们在ClickHouse中根据每个物理机的CPU和内存情况做了一些参数优化,主要是一些merge或者是一些并发还有query这些参数,这里给出一些建议,包括内存、CPU跟核数pool_size的一些关系,我们都做了跟物理机相对应的一些优化。
11. 物化视图
说完ClickHouse之后就必须说一下它的物化视图,ClickHouse的物化视图是一种查询结果的持久化,查询起来跟表是没有区别的,也是一张时时刻刻在预计算的表。创建的过程也是一个特殊引擎,加上后来的as select来表达所需要的列和规则,搞ETL的同事看这个语法就比较亲切。如果需要历史数据可以进行初始化,但是要加上一些关键字,不过关键字一定要慎用,数据量大的话会对整个集群造成性能影响,而且原表往物化视图导入数据的时候,需要加POPULATE关键字并且要停止写入,否则新的时间写入的数据会被直接丢掉,所以物化视图如果不停写入的话数据是不准的。我们使用物化视图的过程中也体会到它的一些优点和缺点,优点是真的很快,图中可以看到物化视图查询选择的数据量少了很多,这也可以理解,它相当于把结果数据给查好了,然后把物化视图对外提供AD-Hoc服务,给别人感觉是毫秒级的AD-Hoc服务,是非常适合的。缺点是对于部分场景使用有限制,更多的是一种累加式的技术,并不是我们想说的哪种随时可以做历史去重的物化视图。
04
唯品会未来展望
1. Presto未来方向
智能自动扩缩容:刚才我们也说到,我们跟离线团队这边有一个借调,并且有一个路由功能,但是我们觉得这个路由还不够智能,因为现在还是我们每天晚上定一个定时计划,几点把这些集群停一部分,把查询打到另外一些集群,再把这些机器给到离线,第二天早上以相反的步骤回来。我们是想我们已经有这种整个链路的查询信息监控,我们可以把这个东西做到智能化路由的概念里面,去根据流量来进行智能的扩缩容。
智能路由:路由智能扫描,假设这个集群非常忙,那就把这个集群智能直接切断,不需要以前还有个打分步骤在里面。
大查询spill to disk:这个我们现在已经有部分集群在给有超大查询需求的AD-Hoc这种场景跟它对应。我们拿出一两个presto集群去开了spill to disk集群来用,后续我们也会结合智能路由,智能分辨执行计划里面读的表源数据非常大的话,就直接给它丢到这个spill to disk集群里。
查询生命周期监控:我们一个查询从connector端发起到在我们多少个worker在跑,每个worker上面为它分配了多少的内存,是怎么去跑这个SQL的,我们想做监控力度更细一点的监控。
机器学习历史查询分析:因为我们现在是把presto所有查询全部放到hive表里面,这些历史的query信息,包括query的力度、stage力度和更细的task力度,以及query自己的Presto自带的API信息,我们全部是在hive里。我们是可以对这些数据进行一些机器学习,来分辨出好的SQL跟不好的SQL,能看下未来把这些相同的SQL丢到什么样的集群里面更适合它跑,这些都是我们未来可以去研究的方向,并且现在有些东西我们现在已经正在实现了。
2. ClickHouse未来方向
Clickhouse未来的方向,包括以下几个方面:
RoaringBitmap留存分析:这个我们现在已经正在给人群做了,但是人群数据现在确实非常多,我们是有几千亿的数据。一两百亿的数据我们现在已经用Bitmap去实现并且比较方便,但几千亿的数据要解决的第一个问题就是从hive怎么每天把数据导到Waterdrop,现在我们是根据多分区的方式去做,首先需要机器的内存比较大,其次是机器基数比较多,才能把这些数据平均分配到每个节点上,再进行Bitmap生成,查询的时候会稍微好一点。
存算分离:存算分离的话我们这边调研了一些底层的存储像XSKY还有JuiceFS,我们跟JuiceFS也是做了一些深度的交流,他们现在只支持按照用这种代理FS的方式去骗过ClickHouse让它以为这个JuiceFS就是本地的存储路径。用这种方式做存算分离的话,能解决因为存储不足而造成的扩容问题。未来我们也是把计算写入和查询打到k8s上面,跟Presto一样,存储放到JuiceFS或者找一些其他FS甚至自己去开发做这样的事情,能真正达到首先读写分离,其次是做存算分离。
接入管控工具:我们现在正在开发一个管控工具,因为CK很多人都说它是手动挡,很多东西需要你自己去看怎么去用比较好。
权限管控RBAC:现在官方文档也给出来了一个RBAC,通过GRANT这些通用的数据库的一些权限,授权和管理的这些特色命名来使用。
资源管控:我们跟Presto一样想把它做到给不同的租户申请不同的资源,特别是存算分离的话我们是给他拉起多少个k8s集群,底层JuiceFS分配多少的空间,这个都是在我们的考虑范围之内的。
05
问答环节
Q:K8s上的Presto集群数据是存在单独的HDFS集群上吗?
A:刚才也提到过我们有很多的Catalog,所以说我们的presto可以理解为不是只为HDFS服务的这么一个引擎。在存储方面,Presto本身也是存算分离的概念,我们的k8s集群里的存储,每一台物理机有一个900G的SSD作为系统盘和Presto的一些日志盘,整个的存储不在这上面,我们是通过Catalog打到第一个Hive上,我们是有6个这样的Hadoop集群,然后把hive搞到一块。Kudu用的是Kudu自己存储,还有MySQL也是用的自带的,所以说我们这边的存储跟k8s是没有任何关系的,所以我们Presto上k8s是有天然的优势的。
Q:怎么保证Presto集群和存储的这部分的网络带宽?
A:第一个就是我们在上云的时候,首先分析了机柜的路由器到每台物理机,从单万兆网卡到双万兆网卡,分析了我们一些业务流量包括刚才说的K8S的亲和性和反亲和性。这样的话其实我们每一台物理机上面,包括每一个机架上面跑的Presto二十多个业务。我们是把高流量业务跟低流量业务都打上各自的标签,保证在一个路由器下的机柜里面,这些物理机从小到一台物理机上的多个worker,大到机柜再上升到整个路由阶段,我们都做了业务的亲和性和反亲和性来平均balance的分配,不会造成所有的重量级业务全部压到一台物理机、一个路由上面,我们是通过这样的一个监控 路由改造 业务平衡来达到这样的效果。
Q:murmurHash3_64在Java侧适配了哪些ClickHouse类型?
A:我们目前基本上是用的id类型,其他类型的话取决于你想做什么样的事情,如果是用varchar类型的话也是可以的,但是varchar类型我们试过,性能没有数字类型好。ClickHouse原来也是varchar类型,但是我们特意去为它的性能做了一个对应的维表,把原来的varchar类型的id转成了int类型的id然后再用murmurHash3_64,所以说我觉得我们如果做到极致优化的话,是应该要存在这样一张维表。刚才也说了我们很多维表都可以用Redis或者Hive,Hive当然会慢一点也是加载到内存里,Redis会更通用一点,我们是有一层这样的维表的转化,转化到int类型以后,也是为了ClickHouse本身的一个性能的考虑,也建议大家都这样去用。