某项目使用 持久化 : 设备接入服务器->事件汇总服务器 (调用特征提取,生成 id)->kafka(特征) + Hbase(大图小图)
告警流程 : 事件汇总服务器->kafka->告警判断 (拉取比对库对比,spark stream)->告警放入 kafka->应用服务器拉取
订阅发布流程 : 事件汇总服务器订阅所有的事件消息->web 登录后查询并缓存所有事件汇总服务器->web 订阅消息给事件汇总服务器->事件汇总服务器根据订阅策略分发消息到 web
如何发布给用户,每个用户一个 topic 或流处理分析? –No
所在的流程节点,在告警分析后?如果在后面,那么发布有延迟;并行处理的?流分开处理了额么,如果分开同步处理,那么可以有单独的服务器再次拉取,费流量。–并行处理的
订阅分发考虑主要有两个因素,用户数量,事件更新的频率
解决方式有如下: 所有卡口最新的事件缓存到队列,按照时间缓存,比如前端 5 秒钟拉一次数据,那么简单的方式,事件更新不频繁,缓存都放在内存或 Redis 中,查询如果频繁,放到内存,如果不怎么频繁 Redis。这能解决大多数的问题,因为缓存的只是消息体,图片需要去自己拉取。每个消息 1k,每秒有 1k 的消息,缓存 5 秒,才 5M 的体积。
如果消息比较多,这是一般的场景,可以使用 spark stream 根据订阅分发策略进行处理,如果订阅用户不多,那么可以放入 kafka 的 topic 中,订阅者一般是 web 端,这可能要有限流策略,有个消息的丢弃策略,否则更新太快,前端也拉取不了,这偏应用,web 端自己做。但是每个用户一个 topic 的方式,对于 kafka 也是个问题,如果 topic 不及时清理,或者突然用户增多,虽然 kafka 能支持 10000 个 topic,但是每个 topic 都有对应的文件,到时候 IO 对系统会产生比较大的影响。
为了达到顺序的目的,msk 的 key 是卡口设备的 id,这样就能保证一个卡口下的事件到达同一个 partition 这样,在这个 partition 内就是有顺序的。为了保证以后提高吞吐量时候,partition 的 num 导致的瓶颈,一般 partition 会有 “预 partition” 的操作。
交通项目性能分析
人脸项目使用经验,kafka 远没有达到性能使用的瓶颈。
官网推荐的测试一个 benchmark: Single producer thread, no replication
821,557 records/sec
(78.3 MB/sec)
消息大小是 100byte 大小,有 80w 每秒的写入速度。这里,测试只用一个小的 100byte 的消息是应为更能测试出 records/sec,如果每个消息体积越大,在 MB/sec 上的吞吐量会有更好的数据。
读取上,一个简单的测试结果,同样是 100byte 大小: Single Consumer
940,521 records/sec
(89.7 MB/sec)
机器配置如下: Intel Xeon 2.5 GHz processor with six cores
Six 7200 RPM SATA drives
32GB of RAM
1Gb Ethernet
非常普通的机器,吞吐量写入有 80w,读取有 90w,远远满足于现在项目需求。项目中,写入大概数量级在 1k 左右,读取不会超过 1w。
从 IO 方面上分析,如果一条消息 1k,网卡 90MB/s 的速度,单千兆网卡有 9w 的吞吐量,也是没什么问题的。
交通项目使用流程
事件持久化
设备接入服务器->图片写入云存储->kafka(过车事件 topic)->数据清洗->告警分析->入库
订阅发布
应用服务器订阅所有过车事件->web 使用 websocket 连接服务器->应用服务器实时对过车数据分析推送到各个 web
吞吐量 kafka 配置
默认情况下,Kafka 根据传递消息的 key 来进行分区的分配,即 hash(key) % ,如果消息没有 key,Kafka 几乎就是随机找一个分区发送无 key 的消息
如果你的分区数是 N,那么最好线程数也保持为 N,这样通常能够达到最大的吞吐量。
资源消耗 不建议为 kafka 分配超过 5g 的 heap,因为会消耗 28-30g 的文件系统缓存,而是考虑为 kafka 的读写预留充足的 buffer。Buffer 大小的快速计算方法是平均磁盘写入数量的 30 倍。推荐使用 64GB 及以上内存的服务器,低于 32GB 内存的机器可能会适得其反,导致不断依赖堆积机器来应付需求增长。(我们在生产环境使用的机器是 64G 内存的,但也看到 LinkedIn 用了大量 28G 内存的服务器。)
10w 吞吐量,单台应该是不够了,按照上述描述,每个消息 1k,读写一共只有 10 个,需要 5+30+1k10w10 = 36G
topic 应该有多少 partition On the consumer side, Kafka always gives a single partition’s data to one consumer thread. Thus, the degree of parallelism in the consumer (within a consumer group) is bounded by the number of partitions being consumed.
这里有点,一个 partition 同一个时刻只给一个 consumer 进行消费,原因其实不复杂,最大利用磁盘顺序读取的速度么。
参考