慌了
本来是个愉快的周一,牛马刚到公司打开企微,发现群里聊天 99+,以多年牛马敏锐的嗅觉判断,不好,产线出问题了!
有反馈说部分员工处理的数据量很多,其他员工很少,有些员工压根就没数据要处理。
原因
有个需求是这样的,系统会定期,根据配置,可能是每 10 分钟、每半小时、每小时等等,把数据根据场景,按照一定的规则,分给员工处理,这里的规则很多,并且有优先级关系,如果满足高优先级的规则,那就不会继续匹配,有个兜底的规则是会提供一些员工 ID,如果以上的规则都没匹配到,那就按照给的员工 ID 列表平均分。
为了提高效率,系统采用多线程并行的方式,每 n 条数据为一份,总共 k 份,并发处理。
假如员工 ID 列表的长度是 m,那最终每个员工,预期至少分到 n/m 条,有 n%m 个员工,分配到的数量比其他员工多 1 条,如果有 k 份数据的话,最终就是多了 k 条。
这个方案其实有两个问题:
- 当 k = 1 ,并且 n < m 的时候,那样始终只有部分员工处理数据;
- 当 k 很大的时候,始终有部分员工处理的数据比其他员工多;
其实在这个方案落地的时候,已经识别到了这个问题,但是当时的普遍情况是,m 很小,k 很大,也就是数据很多,部分员工处理的数据多几条不是什么太大的问题,所以方案就直接上线了。
然后...说啥来啥,问题这不就来了。
产线上出现了 m 比 n 大的场景,也就是说,始终有 m - n 个员工,无数据处理!
这时候团队内有个大聪明说了,增大 n,调整到比 n 大,简单,so easy。(没错,正是在下)
这个方案看起来没什么问题,调大每份数据量,保证能完全覆盖 m,这样每个员工都能分到数据,完美!
事实上这个确实能解决一大部分场景,我们的数据一般都会比较大,但是这个场景下,数据量每天都不会太多。那就会导致虽然调大了 n,但是数据量根本就达不到 n 啊,在数据量比 m 还小的情况下,按当前的规则,还是无法解决数据只分给部分员工的问题。
罪魁祸首
其实最核心的问题,就在于系统为了提高效率,并发处理数据,在处理数据的时候,都是各自按照平均分的逻辑处理,并没有关注到整体平不平均的情况。
这个问题在方案落地前,已经识别到了,一方面觉得数据量会很多,这种情况不需要太多关注,一方面因为整个分配的逻辑很复杂,认为如果需要保证完全平均,得加锁,影响性能。
但现在已经变成不得不解决的一个问题。
说下当前的实现方案,其实很简单,就是利用 Redis,充当计数器的功能。
整体的设计思路就是用 Redis 维护一个步长为 1 的计数器,代码取到这个计数器后,对员工列表长度取余,计算出当前要分配给的员工下标。
这样既能保证整体的分配效率,又能实现平均分的效果。
总结
其实单纯看这个问题的话,觉得解决方案不是很简单吗?但是我们在解构复杂系统时,我们常陷入认知的达芬奇悖论------越是看似简洁的解决方案,往往暗含着未被照亮的认知盲区。当业务场景层层叠加,开发者的思维坐标无法同时精确把握需求的全貌与实现的路径。因此,技术成长本质不是在修正错误,而是在解构认知的巴别塔。
我是欧达克,祝你幸福。