高并发场景下缓存和数据库双写一致性问题及其解决方案
2021-01-12 14:25:23 0 举报
大型缓存架构项目-高并发下的缓存和数据库双写一致性问题的解决思路
作者其他创作
大纲/内容
request是写请求
queue.take()
取出request
request.process()
request是读请求 & flag = null
阻塞队列
轮询等待模块
详解
内存队列10
根据flagMap中该商品id对应的标识位,可以判断出该请求对应的该商品其他的操作请求在队列中的情况。
return Response
异步处理请求
更新库存的请求
读的时候,先读缓存,缓存没有的话,再读数据库,然后把结果放入缓存,并返回响应。
RequestProcessorThreadPool
- threadNum = 10- threadPool = Executors.newFixedThreadPool(threadNum)- requestQueue = RequestQueue.getInstance()
+ RequestProcessorThreadPool()+ init()
内存队列1
读请求去重模块详解
return
request = queue.take()
5. 读请求的结果
不为null
2. 更新mysql数据库网络原因阻塞了...
1. 先删除redis缓存
RequestProcessorThread成员变量:ArrayBlockingQueue<Request> queue
线程1
读请求去重
内存队列List
Callable
3. redis为空
包括两个步骤
productInventoryService.setProductInventoryCache(productInventory)
null
双写一致性问题在以后的读请求到来时,都是在redis中读取的旧数据,并不是和mysql中最新的数据一致。
解决方案
轮询redis缓存
4. 读取mysql数据成功
读库存的请求
while(true)
Cache Aside Pattern
线程池
mysql
强制刷新redis缓存-不对读请求做去重处理
redis缓存
request是读请求 & flag = true
request是读请求 & flag = false
实现接口
从数据库中,强制刷新redis
不强制刷新redis缓存 - 对读请求做去重处理
servlet启动时执行init
每个线程自从创建开始,都会一直while(true)下去
6. 此时步骤2更新完成
线程和阻塞队列的关系
线程2
超时
根据商品id路由到阻塞队列中
读请求去重模块
写的时候先删除缓存,然后在更新数据库。
线程10
...
productInventoryService.findProductInventory(productId)
InitListener
内存队列2
0 条评论
下一页