需求
- 平台交易时,根据金额,时间,地点等要素获得合适的商户,发往银行通道,完成交易。
实现
轮询算法
数据库RAND实现
-- 数据库生成随机数,排序,在表中数据较多情况下,速度很慢
select *, RAND() rand from table_name order rand limit 1;
数据库 ID>MAX(ID)-MIN(ID) * RAND() + MIN(ID) 实现
- 数据ID平均分布时可用,当时我们经过多种条件查询后的可用商户,ID分布往往不是平均分布,造成各商户轮询几率差别巨大。
redis缓存实现
- 优点:速度快,对数据库压力小
- 缺点:难以实现通过多条件查询
数据库排序实现
- 轮询池增加last_choose_time上次更新时间字段,每次挑选后更新,然后取limit 1值,每次使用最长时间未用的商户
- 优点:实现简单,整个商户池都可以均等被使用
- 缺点:高并发情况下,难以控制不会一个商户不被两笔订单同时选择。
程序实现
- 多步实现,首先统计预计可用商户数量 n,然后获得[0,n/2)的整数值 c,通过sql查询 通过上次挑选时间排序last_choose_time,获得limit c,1的数据。查询到数据后,更新last_choose_time到当前时间,已使用次数+1。
- 优点:比较适合我们的需求,和我们的下游商户和商户池地区命中率。可以实现高并发下的商户随机轮询,并且能实现所有商户的使用。
- 缺点:需多次查询,先统计个数,再实际查询数据。