一、 Redis特性
1.速度快
(1)所有数据都是存放在内存中
(2)底层是用C语言编写
(3)Redis使用了单线程架构,预防了多线程可能产生的竞争问题2.基于键值对的数据结构服务器
Redis的全称是Remote Dictionary Server,主要提供5种数据结构:String,List,Set,ZSet,Hash。
3.简单稳定
Redis直接自己构建了VM 机制 ,因为调用系统函数,会浪费一定的时间去移动和请求。
4.客户端语言多
5.持久化
两种持久化方式: RDB和AOF。https://www.jianshu.com/p/fb5627666ad3
6.主从复制 https://www.jianshu.com/p/a7b0c8de83ae
7.高可用和分布式
二、Redis使用场景
1.缓存功能(String)
UserInfo getUserInfo(long id){
// 定义键
String userRedisKey = "user:info:" + id;
// 从Redis中获取值
String value = redis.get(userRedisKey);
UserInfo userInfo;
if(value != null){
// 将值进行反序列化为UserInfo并返回结果
userInfo = deserialize(value);
}else{
// 从mysql中获取用户信息
userInfo = mysql.get(id);
// 将userInfo序列化,并存入Redis,添加1小时过期时间
if(userInfo != null)
redis.setex(userRedisKey, 3600, serialize(userInfo));
}
return userInfo;
}
2.计数器应用(String)
long incrVideoCounter(long id){
String key = "video:playCount:" + id;
return redis.incr(key);
}
3.共享Session(String)
4.限速(String)
很多应用出于安全的考虑,会在每次进行登陆操作时,让用户输入手机验证码,从而确定是否用户本人。但是为了短信接口不被某个用频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次,伪代码如下:
String phoneNum = "130xxxxxxxx";
String key = "shortMsg:limit:" + phoneNum;
// SET key value EX 60 NX
String isExists = redis.set(key, 1, "EX 60", "NX");
if(isExists != null || redis.incr(key) <= 5){
// 通过
}else{
// 限速
}
5.分布式锁(String)
由于Redis的单线程命令处理机制,如果有多个客户端同时执行setnx key value,根据setnx的特性只有一个客户端能设置成功,因此setnx可以作为分布式锁的一种实现方案。
(nx:键必须不存在,才可以设置成功,用于添加)
(xx:键必须存在,才可以设置成功,用于更新)
6.消息队列(List)
Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lpush从列表左侧插入元素,多个消费者客户端使用brpop命名阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。
7.社交网络(Set)
计算两个用户共同的爱好,可以求两个Set的交集。
8.排行榜系统(ZSet)
(1)添加用户的点赞数
比如用户duxin上传一个视频,获得666个好友点赞,使用ZSet的zadd功能:
zadd user:ranking:2018_04_26 duxin 666
然后又获得了一个点赞,使用ZSet的zincrby功能:
zincrby user:ranking:2018_04_26 duxin 1
(2)取消用户的点赞数
zrem user:ranking:2018_04_26 duxin
(3)点赞数最多的前10个用户
zrevrangebyrank user:ranking:2018_04_26 0 9