一、项目背景
清洗的结果中有两张比较大的表:
1)ip域名关系首次发现统计表,日增约0.5亿;
2)ip域名关系历史变化轨迹统计表,日增约1.4亿;
前端查询方式包括以下两种方式:
1)查询某个ip的信息,例如:select * from xxx where ip='xxxx'
2)查询某个域名的信息,例如: select * from xxx where dn = 'xxx'
二、clickhouse
优势:
1)数据压缩率高、写入性能高;
2)主键最左侧列出现在查询条件中时查询耗时在1秒内。(实测数据44亿,公司wiki其他项目组测试数据在百亿级别)
存在问题:
1)只有主键中的第二列出现在查询条件中时,查询速度很差,实测数据量在十亿级别时耗时在几十秒甚至查不出。
官网中也提到过该问题,见下图:
(来源:https://blog.csdn.net/bluetjs/article/details/80322497)
2)不能保证数据全局唯一,clickhouse的主键并不能约束数据唯一性,即使使用ReplacedMergeTree,也只能保证分区内数据唯一。
3)跳数索引作用不大,实测过set、ngrambf_v1、tokenbf_v1。(后两者均为布隆过滤器)
三、impala+kudu
由于clickhouse存在类似主键“最左原则”问题,导致无法同时满足dns反查的应用场景,变通的解决方案是同时存储两份数据,一份使用ip作为主键,另一份使用域名作为主键,前端不同查询场景分别转换为对这两份数据的查询,但这种解决方案存在数据不一致的隐患,一旦出现两份数据不一致时对数据的比对、修复等都是件麻烦的事情,此外还增加了数据同步任务维护的负担。
思考是否存在一种存储方式能够同时满足两个主键的索引(或分区)。
kudu可以支持同时按hash和范围分区,例如:
PARTITION BY HASH (id) PARTITIONS 4,
RANGE (sku)
(
PARTITION VALUES < ‘g’,
PARTITION ‘g’ <= VALUES < ‘o’,
PARTITION ‘o’ <= VALUES < ‘u’,
PARTITION ‘u’ <= VALUES
)
这样在原理上是能够支持分别按单列作为查询条件的应用场景。
四、clickhouse与kudu对比
clickhouse impala+kudu
服务器情况 单机128G 24核 4台 128G 24核
集群支持情况 支持,但对zk的依赖过重 支持,不依赖zk,内部使用raft算法;可在CDH中管理impala和kudu
数据一致性支持情况 不能保证数据一致性,即使使用ReplacedMergeTree,也只能保证分区内数据唯一 支持upsert操作,能够保证唯一性
占用磁盘空间 44亿69g 31亿163G
写入速度 10万/s 23万/s
查询速度 10亿数据量时:只有主键中最左侧列作为查询条件时耗时在1秒内;当主键中最左侧列不在查询条件中时耗时在几十秒 29亿时分别将ip和域名作为条件查询耗时均在1秒内;63亿时ip作为条件(range分区)时,耗时大部分在1~2秒,部分查询时间在几十秒(原因待查)域名作为条(hash分区),耗时基本在1秒内
并发 不支持大并发查询 不支持大并发查询
kudu查询性能记录
1、集群描述
3个master 3个tabletserver
128G内存(设置kudu和impala可用内存上限均为80G) 24核
2、不同条件下的查询时间记录
数量 | dn作为条件查询 | ip作为条件 |
---|---|---|
29亿 | select * from kd.t_ip_dn_first_test2 where dn= 'lovelit.org' limit 10; 0.24 0.13 0.13 | select * from kd.t_ip_dn_first_test2 where ip_num='1806320426' limit 10; 0.85 0.84 0.73 |
63亿 | select * from kd.t_ip_dn_first_test2 where dn= 'lovelit.org' 1.99 0.12 0.12 | select * from kd.t_ip_dn_first_test2 where ip_num='1806320426'; 1.28 1.33 1.30 |
110亿 | select * from kd.t_ip_dn_first_test2 where dn= 'lovelit.org' 2.21 0.11 0.13 | select * from kd.t_ip_dn_first_test2 where ip_num='1806320426'; 111.12 4.78 2.59 |
3、数据量为28亿时的查询记录
总数:
将dn作为条件查询:
4.png 5.png将ip作为条件查询:
6.png4、数据量为63亿时的查询记录
总数:
将dn作为条件查询:
8.png将ip作为条件查询:
9.png在某些时候查询速度一般(第一次查询慢,再次查会快),
10.png5、数据量为110亿时的查询记录
总数:
11.png
将dn作为条件查询:
12.png将ip作为条件查询:
13.png附录: 一些其他对比
clickhouse | kudu | |
---|---|---|
并发qps | 100qps/s | 100w/s |
join支持 | join写法比较特殊;最新版已支持类似SQL的join,但性能不好;无论是Left Join 、Right Join还是Inner Join永远都是拿着右表中的每一条记录到左表中查找该记录是否存在,所以右表必须是小表 | 与impala或sparksql集成后支持标准sql |
小批量写入对性能影响 | 尽量做1000条以上批量的写入,避免逐行insert或小批量的insert,update,delete操作,因为ClickHouse底层会不断的做异步的数据合并,会影响查询性能,这个在做实时数据写入的时候要尽量避开 | 无影响 |
cpu | Clickhouse快是因为采用了并行处理机制,即使一个查询,也会用服务器一半的CPU去执行,所以ClickHouse不能支持高并发的使用场景,默认单查询使用CPU核数为服务器核数的一半,安装时会自动识别服务器核数,可以通过配置文件修改该参数 | 低 |
查询性能 | count: 千万级别,500毫秒,1亿 800毫秒 2亿 900毫秒 3亿 1.1秒 group: 百万级别 200毫米,千万 1秒,1亿 10秒,2亿 20秒,3亿 30秒join:千万-10万 600 毫秒, 千万 -百万:10秒,千万-千万 150秒 | 高 |
使用场景 | 不适合分析场景,聚合排序 | 既有随机(hbase擅长)又有批量扫描(hdfs顺序读写) |
优点 | 1、高效使用cpu2、顺序IO,因此对磁盘没有要求3、索引不使用B树,不受最左原则限制,只要字段在索引中就可以4、写入速度非常快,50-200M/s,对于大量的数据更新非常适用。 | 1、可以解决流式计算结果的更新;2、 |
缺点 | 1、不支持事务2、不支持高并发,官方建议100qps/s3、耗cpu | 1、只有主键可以设置range分区,且只能有一个主键;2、pyspark连接kudu时不支持调用kudu本地库,scala spark支持,支持kudu的各种语法(哪些语法?)3、shell不能查询到表的schema,可通过impala和spark的dataframe获取4、时间格式是utc格式的,差8个小时 |
总结 | 可作为dws宽表层使用,减少join查询 | tserver不要超过100台,单个tserver支持100个tablet,单个tablet支持10G数据,单表最多使用100个tablet;因此:1、不适用pb级数据;2、每台tserver支持1T数据3、单表最大1T数据 |
网友评论