1.redis五种数据结构

1.1 String字符串类型,对应java字符串类型

用户信息序列化后,可以用string类型存入redis中
批量读写string类型,见效网络消耗
数字类型的string类型,可以自增自减操作,有一个大小限制。

1.2 list类型,对应java的LinkedList,链表结构。

增删O(1),查询O(n)
异步队列,一边线程塞入,一边线程取出消费。
结构又和java的不同,多个ziplist组合成quicklist

1.3hash字典类型,对应java的HashMap,是数组+链表结构。

扩容:java是一次性rehash,redis渐进rehash,redis新旧结构两个一起存,然后定时任务慢慢移动,保证了高性能。
可以存储用户单个对象,好处是可以获得单个字段,坏处比起String类型架构占用更多的空间。

1.4set(集合)对应java中的HashSet,无序不重复。

可以做抽奖,去重保证一个人不会中奖两次。

1.5zset(有序集合)

存粉丝:value用户id,socre关注时间。
学生成绩:value学生成绩,socre学生分数
数据结构跳跃列表结构,分等级结构,这样快速的定位插入。

2.应用一:分布式锁

获得锁
setnx key value
存活时间
expire key time
中间异常没有释放锁,加一个存活过期时间解决。
不是原子操作?redis2.8用一条命令操作,后面学习。
超时问题,后面学习。
可冲入锁,后面学习。

3.应用二:延迟队列

异步消息队列,不能保证消息可靠性极致的追求。
list(列表)作为异步消息队列的使用,rpush/lpush入队列,lpop/rpop出队列。
队列空了怎么办?一直获取对cpu有压力,java休眠1s,会有延迟,多个消费者可以降低延迟。
上面问题可以用 blpop/brpop解决,b表示blocking,也就是阻塞读,没有数据就会自动休眠,完美解决上面的问题。注意:长时间没有数据,服务器会断开空闲连接,java编写客户端消费者注意捕获异常进行重试。
锁冲突处理?当前无法获得锁
抛出异常,通知用户稍后重试,调到对话框让用户点击重试,进行重试控制。
sleep 一会再重试。会阻塞当前的消息处理线程,导致队列的后续消息处理出现延迟。
请求转入延时队列中,过一会再试,适合异步消息处理。
延时队列实现?没看懂,后面再学习。