第七章:druid.io实践分享之Realtime+kafka 二

本节重点介绍在运行过程中,这两个组件会出现什么问题及解决方式
场景如下:
场景1、第一次上线kafka的partition与realtime的个数关系
场景2、kafka数据写入最优方式
场景3、realtime配置文件在实际过程的变化及重点参数
场景4、segment堆积产生的原因及如何避免
场景5、realtime对JVM的要求
场景6、多个dataSource,大小表拆分,多topic消费

场景一

初次上线要当前的数据量、集群规模等因素来综合考虑。基本定律是(以一个topic为例):
partitions=N*realtimes
partitions表示当前topic的分区数
N表示每台realtime消费的partition的个数
realtimes表示realtime节点总数

举例说明:
3个partitions,3台realtime,那么N就是1。表示每台realtime节点消费1个partitions。
6个partitions,3台realtime,那么N就是2。表示每台realtime节点消费2个partitions。
同理都是类似方式计算。
为撒这样计算?主要考虑就是均衡,充分利用好每台realtime节点的资源。

随着数据量的增加,会碰到当前topic的消费速率变慢的情况,这个时候就会对kafka集群增加节点或增加kafka节点硬盘或扩展partition个数。
增加节点和增加硬盘都属于kafka本身的操作,不会影响到realtime这层。但扩展partition个数时,realtime节点在水平扩展的时候,就需要考虑下realtime节点增加的个数(参考上面的公式来算)。

场景二

kafka写入最优方式是均衡,如果不均衡,会影响到两个点:

  1. kafka节点有些硬盘会报警并且通过监控平台会发现有些机器负载高,有些负载低。
  2. 接着带来就是realtime消费的不均衡,也会导致有些机器负载高,有些负载低。

所以使用新的hash算法(这个调整后一定要进行测试验证),我们重新开发了分配算法。默认情况下,Kafka根据传递消息的key来进行分区的分配,即hash(key) % numPartitions。
但因为Key的关系默认情况下,写入各partition数据还是会出现不均衡的。
调整成轮训方式即可。

场景三

这里先说的参数重点是指runtime.properties文件里属性druid.realtime.specFile所对应的json文件内容。涉及的参数如下:
第一:shardSpec
第二:rejectionPolicy
第三:intermediatePersistPeriod ≤ windowPeriod < segmentGranularity 和 queryGranularity ≤ segmentGranularity

**shardSpec**

默认设置成

"shardSpec": {"type": "none"}

这种情况单机版还可以玩一玩。在多个realtime节点的情况下,这个不能这样设置了。
现在官方文档提供:linear and numbered,但在源码中还提供了另一种SingleDimensionShardSpec,这种使用较少。
这里可以给大家分享一下,当多个realtime节点时还配置成默认值的效果(这是当初文档没有现在这么详细导致我们疏忽了),那么就是当前小时范围内的数据是跳跃的,简单的说,就是同一个查询条件发多次,返回的结果集大小不同,有时候返回30多条,有时候又返回50多条。在当时对初学的人来说很紧张,后面通过源码分析和大家的努力,终于发现了是这个参数配置失误导致。
但这个调整是有要求的,就是调整完后,必须对当前时间段realtime所有节点已经存储的数据要删除掉,不然查询的结果还是跳跃的。
举例说明:
当前时间段是12点-13点(假设segment是按小时进行),我是在12点20分调整此参数,那么再重启全部realtime节点之前,必须把12点-13点之间已经持久化的数据要删除掉,不然调整成linear后,是没有任何效果的。这个步骤非常重要
另外注意下:
realtime 节点1设置为:
“partitionNum” : 1
realtime 节点2设置为:
“partitionNum” : 2
realtime 节点3设置为:
“partitionNum” : 3
依次类推。
关于numbered和linear的区别很小,主要在查询上面的限制,大家查看官方文档再实践下就知道了。

**rejectionPolicy**

此参数要是不理解,带来的效果就是丢失数据,会让你误认为系统有bug。
有三个值:serverTime(推荐使用)、messageTime、none。
如果想不丢弃数据就用none,另外一个用系统时间作为参考,一个用event里的timestamp作为参考。如果此参数是none的话,windowPeriod这个参数就没有什么效果了。
所以当数据有丢失的时候,首先检查时间戳和这个参数。也就是检查数据里面的timestamp和系统时间是否有较大的误差。(提醒下:首先要保证json数据格式要能正常解析)

**intermediatePersistPeriod、windowPeriod、segmentGranularity和queryGranularity**

在实际的使用过程中,这几个参数的关联关系一定要当心。
首先介绍下intermediatePersistPeriod、windowPeriod、segmentGranularity三个是紧密关联的,特别windowPeriod这个参数不光控制数据消费延迟,也控制着segment合并持久化。
并且intermediatePersistPeriod参与的逻辑部分和windowPeriod参与的逻辑部分,是两个线程分开进行的。
举例说明下:

你可能感兴趣的:(druid.io)