一、通用命令
- keys:显示所有符合条件的键(一般不在生产环境使用,时间复杂度O(n)速度慢)
- dbsize:计算key的总数(内部计数器,时间复杂度O(1)
- exists key:判断键是否存在(O(1))
- del key
-
expire key seconds:设置键的有效期,-1代表永久
+type key
image.png
二、数据结构和内部编码
image.png
三、单线程
单线程为什么这么快?
1.纯内存:所有的数据都存在内存中
2.使用多路I/O复用模型,非阻塞IO
多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
3.避免了不必要的上下文切换和竞争,不用考虑锁的问题
单线程需要注意的问题:
1.一次只运行一条命令
2.拒绝长(慢)命令
四、数据结构
1.String
结构和命令:
key-value:value最大为512MB
应用场景:
- 缓存
- 计数器
- 分布式锁
常用命令:
- get、set、del
- incr:incr key 自增1,如果key不存在,自增后get(key)=1
- decr:自减
- incrby:incrby key k 自增k
- decrby
- setnx:key不存在,才设置(添加键值)
- setxx:key存在才设置(更新键值)
-
mget、mset:get、set多个
n次get
1次mget节省了网络时间
- getset、append、strlen
应用:
1.记录网站每个用户个人主页的访问量:
incr userid:pageview
2.缓存视频的基本信息(数据源在Mysql中):
//伪代码
public VideoInfo get(long id){
String redisKey = redisPrefix + id;
VideoInfo videoInfo = redis.get(redisKey);
if(videoInfo == null){
videoInfo = mysql.get(id);
if(videoInfo != null){
//序列化
redis.set(redisKey,serialize(videoInfo));
}
}
return videoInfo;
}
3.分布式id生成器
2.哈希
结构:
hash结构
filed不能相同
命令:
- hget、hset、hdel / 例:hget key field
- hexists、hlen
- hmget、hmset
- hgetall、hvals、hkeys O(n)
应用:
1.记录网站每个用户访问量
hincrby user pageViewCount
3.list
有序、可以重复、可以从左右弹出
命令:
- rpush:从右边插入 lpush
- rpop、lpop
- rinsert、linsert
- lrem O(n)
lrem key count value
//根据count值,从列表中删除所有value相等的项
(1) count>0,从左到右,删除最多count个value相等的项
(2)count<0,从右到左,删除最多Math.abs(count)个value相等的项
(3)count=0,删除所有value相等的项
- ltrim
ltrim key start end
//按照索引范围修剪列表
- lrange
- lindex
- llen
- lset
应用:
1.时间线(微博)
image.png
4.set
无序,不能重复,集合间操作
命令:
- sadd,srem
- 可以做集合间的操作,sinter(交),sdiff(差),sunion(并)
- scard:计算集合大小
- sismember:是否是集合中的元素
- srandmember:从集合中随机挑count个元素,但是不会弹出
- spop:从集合中随机弹出一个元素
- smembers:从集合中取出所有的元素
5.有序集合
有序集合结构
集合VS有序结合
命令:
- zadd、zrem
- zscore
- zcard
- zrange、zrangebyscore
- zcount
- zremrangebyscore、zremrangebyrank