
先捋一下redis的特点:
读写飞快:缓存、高并发;
持久化:但不承诺靠谱;
数据类型丰富:比某些编程语言靠谱多了。C++,你低什么头?
单线程:简化进/线程间同步的问题;
自动过期:缓存、验证码、限时优惠;
分布式:主从热备、海量数据、高并发;
lua:原子性,代替事务,复杂逻辑;
快速、稳定、简单,似乎不负神器之名啊,怪不得redis这几年混得这么滋润。这让我非常有理由怀疑,要不是懂lua的人少,redis都能代替java进行编程了。这可不行,好不容易学了点java,我还没有开始享受人生呢,我得想办法把redis干掉。
我可是要成就皇图霸业之人,怎可有妇人之仁?说干就干,就让我从redis的几种典型应用场景开始下毒吧:
一:缓存
这可能是redis最主流的用法了。然而,据我盲目揣测,可能8成的项目只使用应用内缓存就够了。
分布式缓存的优点不外乎俩条:
分布式一致性 :如果使用应用内缓存,负载均衡下的多台应用服务器返回的数据可能会短暂振荡。但那又怎么样呢?我天朝的互联网玩家都是见过世面之人,抢过票、剁过手,承受能力堪比狗,怎么会在乎这样的小场面?更何况,据一位不愿透漏姓名的某业内人士的说法:缓存就像showgirl,看看就行了,还能指望基于缓存的去更新数据库么?
大且可靠:毕竟不占用应用服务器的JVM内存,不占用GC,而且还可以上集群。如果你的网站量非常之大,缓存更新非常频率,需要缓存的数据非常之多,那么我相信你的公司一定非常有钱,既然买得起redis,那我也就不多说什么了。但如果你像我一样家境贫寒、家徒四壁,我相信足以缓存你所有的配置和数据那1GB的应用内存才是你的最佳伴侣。

二:分布式锁
首先不得不提的是:坊间流传甚广的利用setnx设计分布式锁的方案多为半殘版本,可能导致意外死锁。
复现流程为:假定有三个客户端c1, c2, c3。拿到redis锁的c3意外车祸死亡。c3赶车祸走得急,没来得及把锁还回来,这让发现机会的c1, c2喜出望外,两人迫不及待的先后向redis服务器发送了del, setnx指令,结果c1撬了c3的锁,c2撬了c1的锁。c1和c2都以为自己是那个最终的成功人士,于是弹冠相庆、相互死锁。
参考redis官网辟谣:Design pattern: Locking with SETNX
解决办法倒也简单,使用第三方库就好,干嘛自己设计分布式锁?
然而,我要说的是:除了redis锁、zk锁,其实还有一种数据库锁。本着一事不烦二主的千古箴言,我认为数据库锁可能是多数情况下的最佳选择。当然,这多少需要一点儿技巧,否则太任性的数据库锁可能会成为性能瓶颈。不过我是谁?二十一世纪最伪大的架构师,这点儿小问题怎么可能难倒我?具体怎么玩,等我想好托词再说。
三:消息队列
你别说,这年头真有人拿redis当消息队列(mq)。由于redis中有list结构,不少人用lpush, rpop组合当mq,如果用brpop的话还可以避免主动轮询。而且,由于redis有持久化功能,似乎也不需要担心redis崩溃导致消息丢失的问题了。
但是吧,有一个问题:就是rpop出来那一刻,如果你的服务器进程crash了怎么办?进程crash之前将数据rpush回去嘛?我飞快地提出俩个办法来解决这个问题:一、使用lindex代替rpop取数据,处理完再rpop;二、买租一台真正的mq。
看看,这就是牛逼的架构师啊,一下子提出俩个解决办法那么多
一般来说敢放到redis中的数据都是可以随便丢的,当然如果老板也这么认为那就更好了。
四:计数器
我发现redis的算术竟然还不错,至少很擅长加减,相信也是受益过九年制义务教育的精英。redis提供了各式各样的incr指令,什么incrby, incrbyfloat, hincr, zincrby。投身计数也算是学以致用,比如显示注册用户数、微博点赞数等,特别适合网红大V们百万粉丝齐上阵的特点。
而且,即使redis重启恢复时丢失这么1~2秒的点赞数,好像除了程序员本人之外也没人能看得出来,而程序员本人也不会傻到自己说出来。
我骑了个怪,这中间竟然可以不用到数据库~
麻蛋,竟然黑不下去了。
好了,各种老板你们先忙,我刚刚购买下载了一本redis教程,先去看会儿书了~
参考文献:
进程内缓存与分布式缓存的比较
Design pattern: Locking with SETNX
美团:缓存那些事
Redis常见的应用场景解析
Redis应用场景




