redis使用方法创新,独创使用方法(转载请说明出处):
http://note.youdao.com/noteshare?id=ff42f6b4148298d97dc3ef36af963d6f&sub=7A1C2FA465364079A3377E5CA35765E3
关于Redis使用的思考-创新
方案1、多线程写入场景下,redis缓存和数据库数据的最终一致性思考
(解决双写不一致问题)
优点:数据库并发性更好;
缺点:未解决超卖问题。
ps:数据库version不用作数据库修改的乐观锁,对数据库性能无影响。
version仅用作更新缓存时的版本校验,向上增加允许,向下修改不允许。
(Redis缓存加version,数据库冗余一个version字段,基本实现了canal的功能)
方案2、缓存加version结合数据库乐观锁
对于采用乐观锁场景可以减少数据库读操作;
同时解决了双写不一致问题。
优点:
1、解决双写不一致问题;
2、更新数据前不需要从数据库io读取获得version;
ps:解决了超卖问题(乐观锁本来就可以解决)。
缺点:可能出现大量失败的更新,容易影响数据库性能。
改进:结合分布式锁,可以避免大量失败更新。
方案3、高并发强数据一致性场景提升服务并发性能
优点:
1、提升了数据库使用乐观锁高并发场景下服务性能:大量失败的更新操作提前到服务层发现。
ps:双写问题在分布式锁场景下本不存在。
解决了超卖问题(乐观锁本来就可以解决)。
有数据库乐观锁version控制,不用担心redis主从切换情况下可能出现多个客户端获得同一个分布式锁。(少部分在version校验时会退回到获取缓存逻辑,大部分在执行数据库更新时会失败,此时可能会涉及其他数据库数据回滚处理问题)
缺点:
复杂度增加,分布式锁,version比较,缓存带version。
在非(高并发&强数据一致)场景下,没有必要。在高并发&强数据一致)场景下使用。
PS:
向缓存中添加商品key数量时加上version【过期时间:+随机数】[避免缓存失效(击穿)]
set product_1006 {50,3} 【ex 30 + random】
Lua脚本类似CAS语义:
eval "local x=string.len(ARGV[1]); if redis.call('GETRANGE', KEYS[1], 0, x-1) < ARGV[1] then redis.call('SET', KEYS[1], ARGV[2]); return 1; end; return 0" 1 version 3 3
就这,怎么使用看场景。
谁说redis一致性不行,看怎么使用。
欢迎来拍砖!据说思想的碰撞能引发智慧。