7

遇到一个问题,需要从预插入数据的表,随机找一条,分配给一个用户,求一个简洁的方案

 2 years ago
source link: https://www.v2ex.com/t/837977
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

遇到一个问题,需要从预插入数据的表,随机找一条,分配给一个用户,求一个简洁的方案

  ZSeptember · 1 天前 · 1478 次点击

预先创建一批 coupons ,存到 coupons 表里面,然后将这些 coupons 发给用户,要求是一个 coupon 只能发给一个用户,不能重复发放。

分配性能越高越好。

  1. coupons 分配服务有多实例
  2. 其他服务请求 coupons 分配服务获取 coupon

当前方案:

两个步骤:

  1. 随机读一个 coupon
  2. 分配 coupon 使用数据库事务+乐观锁,保证不重复分配

所以优化重点是:尽量少访问数据库;随机读到的 coupon 尽量不要冲突。

优化方案:

预读取 100 个 coupons 到内存,分配的时候优先从缓存中读取,缓存没有从数据库再读一批。

为了解决多实例读取冲突问题,在 redis 记录一个 coupon id 作为 cursor ,每读一批,将 redis 中的 cursor 更新为最新的,下一批读取的是,id > cursor 的 coupons 。

redis 可以做到 cas 更新 cursor ,可以保证读取的每一批都不会重复。

cursor 也是 30min 失效,下一次继续从 0 开始,就算读取了一批,但是没有分配,然后挂了,被跳过的 coupons 还是会有机会读到的。

因为公司大佬觉得引入 redis ,方案比较复杂,不好维护;想跟大家请教下,看有没有什么更简洁的方案,不用引入数据库以外依赖

第 1 条附言  ·  1 天前

附加一条现状
1. 辣鸡 spanner 没有 random 函数,做不到运行时读取随机

第 2 条附言  ·  1 天前

暂定方案

1. 创建的 coupon 不落数据库,直接 rpush 到 redis queue
2. 分配的时候,直接 lpop 一条数据
3. 分配的时候用 coupon id 做唯一索引控制,保证不会重复分配。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK