使用模拟退火算法优化 Hash 函数

现有个处理股票行情消息的系统,其架构如下:

使用模拟退火算法优化 Hash 函数

由于数据量巨大,系统中启动了 15 个线程来消费行情消息。消息分配的策略较为简单:对 symbol 的 hashCode 取模,将消息分配给其中一个线程进行处理。 经过验证,每个线程分配到的 symbol 数量较为均匀,于是系统愉快地上线了。

运行一段时间后,突然收到了系统的告警,但此时并非消息峰值时间段。经过排查后,发现问题出现在 hash 函数上:

使用模拟退火算法优化 Hash 函数

虽然每个线程被分配到的 symbol 数量较为均衡,但是部分热门 symbol 的报价消息量会更多,如果热门 symbol 集中到特定线程上,就会造成线程负载不均衡,使得系统整体的吞吐量大打折扣。

为提高系统的吞吐量,有必要消息分发逻辑进行一些改造,避免出现热点线程。为此,系统需要记录下某天内每个 symbol 的消息量,然后在第二天使用这些数据,对分发逻辑进行调整。具体的改造的方案可以分为两种:

放弃使用 hash 函数

对 hash 函数进行优化

放弃 hash 函数

问题可以抽象为:

将 5000 个非负整数分配至 15 个桶(bucket)中,并尽可能保证每个桶中的元素之和接近(每个桶中的元素个数无限制)。

每个整数元素可能的放置方法有 15 种,这个问题总共可能的解有 155000种,暴力求解的可能性微乎其微。作为工程问题,最优解不是必要的,可以退而求其次寻找一个可接受的次优解:

根据所有 symbol 的消息总数计算一个期望的分布均值(expectation)。

将每个 symbol 的消息数按照 symbol 的顺序进行排列,最后将这组数组划分为 15 个区间,并且尽可能使得每个区间元素之和与 expection 接近。

使用一个有序查找表记录每个区间的首个 symbol,后续就可以按照这个表对数据进行划分。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjddg.html