1.redis的值可以有string, list, hash, set, zset, bitmaps, hyperloglog, GEO等等
2.redis 是单线程架构
3.redis提佛那个RDB和AOF两种策略将内存中的数据保存到硬盘中
4.使用shutdown关闭redis可使数据得到持久化
5.全局命令:
5.1 keys * : 查看所有键
5.2 dbsize : 查询db下的键总数
5.3 dbsize命令在计算键总数时不会遍历所有键,而是直接获取redis内置的键总数,所以dbsize的时间复杂度为o(1),而keys会遍历所有键,复杂度为o(n)
5.3 exists key : 判断键是否存在
5.4 del key [...key]: 删除键
5.5 expire key seconds : 设置键过期时间
5.6 ttl 查看key还有多久过期
5.7 type 查看key的数据类型
5.8 type 命令实际返回的就是当前键的数据结构类型,他们分别是string,list, hash, set, zset,但是这些只是redis对外的数据结构,实际上每种数据结构都有自己底层的内部编码,而且是多种实现,用 object encoding key命令查看内部编码
5.9 内部编码(string => int enbstr raw; hash => ziplist hashtable , list => ziplist linkerlist quicklist, set => intset, hashtable; zset => ziplist, skiplist)
6.为什么单线程还能这么快
6.1 纯线程访问,内存响应时间大约为100纳秒
6.2 非阻塞I/O redis使用epoll作为I/O多路复用技术实现,再加上redis自身事件,处理模型将epoll中的连接,读写,关闭都转为时间,不在网络I/O上浪费过多的时间
6.3 单线程避免了线程切换和竞争产生的消耗
7.字符串
命令:
set key value [ ex seconds | px millsenconds ] [ nx|xx]
ex|px 设置过期时间, ex为秒 px为毫秒
nx|xx nx:键不存在的时候才能创建 xx键存在的时候才能穿件
7.1 除了set,redis还提供setnx和setex 两个命令(eq:setnx key value ; setex key senconds)
7.2 分布式锁使用setnx 、 expire 、 del 实现
7.3 批量新增 mset ; 批量获取mget
7.4 incr 命令用于对值的自增操作, incr每次递增1,decr每次递减1, incrby(自增指定数量 eq: incrby 10 ; 加10) decrby( 递减指定数量) incrbyfloat(自增浮点数)
7.5 追加值 append; (最好不用,会导致预分配空间增大)
7.6 字符串长度 strlen key (一个中文占3字节)
7.7 设置并返回原值 getset key value
7.8 修改指定位置的值 setrange key offset value ( 从offset开始替换) (不建议使用,跟append一样会导致预分配空间增大) offset 从0开始
7.9 获取部分字符串 getrange key start end
7.10 内部编码 int:8字节的长度整数, embstr:小于等于39字节的字符串, raw:大于39字节的字符串
7.11 开发提示: 计算incr ; 共享session ; 限速
8.哈希(hash)
8.1 命令:
8.2 hset key field value
8.3 hget key field
8.4 hdel key field [...field]
8.5 hlen key 计算key的field个数
8.6 批量新增和批量删除 hmset key field value [ ...field, ...value] , hmget key filed [ ...field]
8.7 判断field是否存在 hexists key field
8.8 获取所有field : hkeys key
8.9 获取所有value : hvals key
8.10 获取所有field-value: hgetall key
8.11 递增和递减 hincrby key field incrment; hdecrbyfloat key field incrment;
8.12 计算value的字符串长度 hstrlen key field
8.13 hsetnx key field value (不存在的时候才创建)
8.14 内部编码 ziplist(压缩列表) 当哈希类型元素小于hash-max-zip-list-entries(默认512个), 同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,redis会选用ziplist作为哈希的内部实现; hashtable, 当哈希类型无法满足ziplist的条件时选用hashtable,hashtable的复杂度是o(1) ,hashtable消耗更多的内存
8.15 用途: 存储用户数据
9.列表 list
9.1 在redis中可以对列表两端插入push和弹出pop
9.2 命令 添加: rpush lpush linsert
9.3 查询 lrange lindex llen
9.4 删除 rpop lpop lrem
9.5 修改 lset
9.6 阻塞操作 brpop blpop
9.7 rpush/lpush key value [ ...value]
9.8 linsert key before/after pivot value (在key列表中查找pivot,在pivot前或者后添加value)
9.9 lrange key start end (查询)
9.10 获取列表指定索引下标的元素( lindex key index)
9.11 获取列表长度llen key
9.12 删除rpop/ lpop
9.13 lrem key count value (从key中找到value,删除count个数据, count=0 表示删除全部 , count>0 从左到右删除,count<0 从右到左删除
9.14 ltrim key start end (裁剪列表)
9.15 lset key index value 修改指定索引下标的值
9.16 阻塞brpop/blpop key timeout ; timeout 表示阻塞时间,如果timeout为0,则一直阻塞下去
9.17 内部编码 ziplist linkedlist quickedlist
9.18 使用场景 1.消息队列 (lpush+ brpop) 2.文章列表( 分页用list,文章内容用hash)
10.集合(set) 不允许重复+无序的
10.1 添加元素 sadd key elememt [...element]
10.2 删除元素 srem key element [ ...element]
10.3 计算元素个数 scard key 复杂度为o(1),不应该遍历所有元素,直接使用内部变量
10.4 判断元素是否在集合中 sismember key element
10.5 srandmember key [count] (count 默认1) 随机从集合中获取count个元素
10.6 spop key [count] 随机从集合中获取count个元素,并删除
10.7 获取所有元素 smembers key
10.8 smember, lrange ,hgetall都是比较重的命令,如果元素过多会阻塞
10.9 求多个集合的交集 sinter key [ ...key]
10.10 求多个元素的并集 sunion key [ ...key]
10.11 多个元素的差集 sdiff key[...key]
10.12 将交集、并集、差集的结果保存( sinterstore destination key [...key] ; sunion destination key [...key]; sdiff destination key [....])
10.13 内部编码 intset( 整数集合),当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个) hashtable :当无法满足intset的时候选用
10.14 使用场景 1.用户标签
- 有序集合(zset)
11.1 添加 zadd key score member [ ...score ...member]
11.2 zadd key [nx|xx] [ch][incr] score member [ ...score ...member](nx|xx 存在的时候才创建| 不存在的时候才创建, ch:返回此次操作后,有序集合和分数发生变化的个数, incr 对score做增加)
11.3 计算个数 zcard key
11.4 计算成员排名 zrank key member (计算score从低到高) zrevrank key member( 计算score从高到低)
11.5 删除成员 zrem key member
11.6 增加成员分数 zincrby key incrment member
11.7 返回指定排名范围的成员 zrange key start end [withscore] ; zrevrange key start end [withscore] 加上widthscore会返回分数
11.8 返回指定分数范围的成员zrangebyscore key min max [widthsocre] [ limit offset count] ; zrevrangebyscore key max min [withscore] [limit offset count] (其中max、min还支持开区间和闭区间 -inf表示无限小,+inf 表示无限大
11.9 可用于排行榜,点击榜,购买榜等等
11.10 zcount key min max 返回指定分数范围成员个数
11.11 删除指定排名内的升序元素 zremrangebyrank key start end
11.12 集合间的操作 (交集和并集 zinterstore , zunionstore)
11.13 内部编码 ziplist:当集合元素小于zset-max-ziplist-entries配置 (默认128个) 每个元素小于 zset-max-ziplist-value配置(默认64字节); skiplist(跳跃表)
12.键重名 rename keyname newkeyname; renamenx key newkey(当newkey不存在的时候才能修改)
13.randomkey 随机获取键
- 过期功能. expire key seconds; pexpire key millseconds; expireat key timestamp; pexpireat key timestamp
15.ttl和pttl都可以查询键的剩余过期时间, 但pttl精度更高,可以达到毫秒级别
16.pexpire, pexpire, expireat, pexpireat 内部都是使用pexpireat实现的
17.清除过期时间 persist key
18.set 会导致过期时间失效
- 迁移键 move key db
20.dump+restore(源目标执行的dump,目标源指定 restore)
21.migrate 用redis实例间进行数据迁移,具有原子性
22.遍历建 keys patten(全量遍历建)
- scan 渐进式的遍历所有键 scan cursor [ math patten] [ count number] 知道cursor重回0就是遍历结束
24.hgetall => hscan
- smember => sscan
26.zrange => zscan
27.scan的问题,如果在遍历过程中键发生变化,(增加、删除、修改)那么可能出现遍历不到,或者重复等现象
数据管理, 切换数据库 select dbindx
清除数据flushdb , flushall
30.慢查询两个配置参数 slowlog-log-slower-than和slowlog-max-len (记录查询日志的单位是微妙,1秒=1000毫秒=1000000微妙)
31.获取慢查询日志 slowlog get [count]
32.重置慢查询 slowlog reset
33.redis-cli 详解
33.1 -r 选项代表将命令执行多次
33.2 -i 每隔几秒执行一次
33.3 -x 代表从标准输入(stdin)读取数据作为redis-cli最后一个参数 eq: echo 'world' | redis-cli -x set hello
33.4 -c 连接redis cluster节点时使用
33.5 --scan和--pattern 用于扫描指定模式的键
33.6 --rdb请求redis生成并发送rdb持久化文件,保存在本地
33.7 --pipe 批量发送给redis执行
33.8 --bigkeys 使用scan对redis键进行采样,从中找出内存占用较大的键
33.9 --eval 执行指定lua脚本
33.10 --latency 测试redis的网络延迟
33.11 --latency-history 分段展示,网络延迟
33.12 --latency-dist 统计图表展示网络延迟
33.13 --stat 实时获取redis重要统计信息
33.14 --raw和--no-raw 要求命令返回的结果必须是非原始类型和原始类型
- redis-server 详解
34.1 --test-memory 检查系统能否稳定的分配指定内存给redis
35 redis-benchamrk详解 (为redis做基准性能测试)
35.1 -c 代表并发数
35.2 -n 选项代表请求总数
35.3 -q 仅显示request,per,second信息
35.4 -r 测试的时候插入更多的键
35.5 -p 代表每个请求pipeline的数量
35.6 -k 是否使用keepalive 1=使用(默认) 0=不使用
35.7 -t 对指定命令进行基准测试
35.8 --csv 将结果按照csv格式数据
36 pipeline概念,光在真空中传输的速度为每秒30万公里,这里假设光纤为光速的三分之二, pipeline非原子性
37 事务与lua
37.1 redis提供了简单的事务功能 multi和exec,multi表示事务的开启, exec表示事务的结束。 discard 表示取消事务
37.2 有些应用场景需要在事务之前,确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁) redis提供watch 命令来解决这类问题
37.3 watch key; multi ....exec
位图bitmaps
38.1 setbit key offset value (offset表示个位值)
38.2 getbit key offset
38.3 bitcount key start end 获取bitmaps指定范围值为1的个数,需要注意的是start和end表示字节数,一个字节=8bit
38.4 bitmaps之间的运算
38.5 bitop op destkey key [...key] ; bitop是一个复合操作,可以做多个bitmaps的and(交集) or(并集) not(非集)xor(异或)操作并把结果保存到destkey中
38.6 计算bitmaps中第一个值的targetbit的偏移量 bitpos key tagrgetbit [start] [end] ; (eq: bitpos name 1 0 5 , bitpos name 0 0 5)
38.7 用途 可用于记录访问量如每日访问量,日、周、月活跃量/签到hyperloglog
39.1 pfadd key element [ ...element]
39.2 pfcount key [...key] 计算独立用户数
39.3 pfmerge destkey scource [ sourcekey ...] 合并
39.4 hyperloglog 内存占有量非常小,但是存在错误率,开发者在进行数据结构选项时,只需要确认如下两条即可:1.只为了计算独立总数,不需要获取单条数据 2.可以容忍一定误差率(官网给出0.81%)毕竟hyperloglog在内存中占有很大的优势
40.发布订阅
40.1 发布 publist change message
40.2 订阅 subscribe change [ ...change]
40.3 有关订阅命令有两点需要注意的, 客户端在执行订阅命令之后进入订阅状态,只能接受subscribe, psubscribe, unsubscribe, punsubscribe四个命令; 新开启的订阅客户端,无法收到该频道之前的消息,因为redis不会对发布的消息进行持久化
40.4 取消订阅unsubscribe change [...change]
40.5 按照模式订阅和取消订阅 psubscribe pattern [...pattern] , punsubscribe pattern [...pattern]
40.6 查询订阅 pubsub change [ pattern] ( 查询至少一个订阅者的频道)
40.7 查看频道的订阅数 pubsub number [...change]
40.8 查看模式订阅数 pubsub numpat
40.9 使用场景:聊天室,公告牌, 服务之间的消息解耦
41.GEO(地理信息定位)
41.1 支持存储地理位置信息,用来实现诸如附近位置,摇一摇这类依靠地理位置信息的功能
41.2 增加地理位置信息 geoadd key longitude latitude member [ ... longitude latitude number] ; longtitude=经度, latitude=纬度, member=成员
41.3 更新数据还是使用goeadd ,但是返回的是0
41.4 获取经纬度 goepos key member [ ...member]
41.5 获取两个地理位置的距离 goedist key member member2 [unit]; unit包含 m=米 km=千米 mi代表英里 fl达标尺
41.6 获取指定位置范围内的地理信息位置集合 goeradius/goeradiusbymember ; goeradius返回具体经纬度, goeradiusbymember 返回成员
41.7 获取geohash geohash key member [...member]
41.8 删除地理位置信息 zrem key member;
客户端
set hello world => *3/r/n5/r/nhello
多条回复:在resp中第一个字节为 *持久化
43.1 redis支持RDB和AOF两种持久化机制
43.2 RDB持久化是把当前过程数据生成快照保存在硬盘的过程,触发rdb持久化过程分为手动和自动触发
43.3 手动触发为save和bgsave
43.4 save命令: 阻塞当前redis服务器, 知道rdb过程完成(废弃)
43.5 bgsave命令: redis进程执行fork操作创建子进程,rdb持久化过程由子进程负责,完成后自动结束,阻塞只发生在fork阶段,时间很短
44.自动触发RDB的持久化机制。使用save相关配置,如“save m n”表示在m秒内数据集存在n次修改触发bgsave
45.执行lastsave获取最后一次生成rdb时间,对于info统计的rdb_last_save_time
46.RDB文件的处理。保存:rdb文件保存在dir配置指定目录下,文件名通过dbfilename配置指定,可以通过config set dir {newdir}和config set dbfilename {newdbfilename} 设定
47.rdb优缺点:优点:rdb是一个紧凑压缩的二进制文件,非常适合备份全量复制等场景,redis加载rdb速度远远快于aof
缺点:没有办法做到实时持久化(秒级持久化) 2.老版本不兼容新版本
48.aof:数据完整
48.1 aof 持久化以独立日志的方式记录每次写命令,重启时再重新执行aof文件中的命令达到恢复数据的目的。aof的主要作用是解决了数据持久化的实时性,目前是redis的主流
48.2 aof的工作流程: 命令写入 --append-->aof缓存--sync-->aof文件 (rewrite)
48.3 aof 缓存区同步文件策略 always: 每次写入都要同步aof文件,在一般的sata硬盘,redis只支持几百TPS ; no:操作系统同步aof文件周期不可控,虽提升了性能,但数据完全性无法保障 ; elerysec:默认配置。命令写入aof_buf后调用系统write操作,write完成后线程返回,fsync同步文件由专门的线程每秒调用一次
49 重写机制:随着命令的不断写入aof,文件会越来越大,为解决这个问题,redis引入aof重写机制