背景: 通过http请求的接口提供对外可消费kafka内部topic数据的需求, 提供多种不同参数的消费方式,提供可获取offset的接口

 

设计思路: 要求有一定的需求速率,例如1秒钟要获取5000条数据,且需单分区。 经过测试在扩大分区的情况下且使用多线程的方式进行测试,可以满足速率要求,但不能符合单分区的要求。限制了单分区,就如同高速公路上只能有一条车道通行,也就限制了速率,不能达到通行速度的要求。

    在此种前提下,后修改为了kafka接Redis中间件,客户端从Redis中获取数据的方式进行实现。大致图解如图所示

java中kafka用法 java kafka_redis

设计要点:

1、为了保证客户端获取数据的多样性,我们提供了3种不同的接口来提供服务,分别为: getMessage、getMessageByOffset、getMessageByParOffset 可以通过数量、offset与数量、分区和offset与数量来进行获取

2、内部自行维护了client获取数据的offset位移,理论层面该offset应与kafka的单分区的offset的位置相同。每当后台线程进行检测时,触发条件是:  redis的队列是否满足预设条件,然后根据已读到位置的offset值继续从kafka中poll出数据,循环写入到redis池子中。

3、支持用户可传此位置或不同位置的offset值,当获取的offset在当前位置之前时,会回至需要刷取数据的offset值的记录,清空Redis池中的数据,等待后台线程轮询写入符合要求的数据,然后client就可以取出数据。

4、提供 getOffsetPartition 接口用于获取该用户下不同分区所获取到数据的offset的值,用户可根据此offset值来进行持续的获取新数据

6、为了避免多台机器执行冲突,在必要维护的位置增加分布式锁,保证同一时刻只有一个任务在进行执行操作。

部分细节处理:

1、修改Redis中的数据时,维护两种Redis的key : kafka_redis_offset 和 kafka_redis_offset_user

前者用于Kafka写入Redis时的数据获取,后者用于用户获取offset位置时获取的记录

2、为了保证主题与数据空间的可用性,在获取首次会首先向Redis队列中写入需要持久化数据的主题信息,然后后台线程才会依据此列表来进行数据的刷取与存取