持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 8 天,点击查看活动详情
一、基础知识
1,redis支持的数据类型:
- string字符串、hash哈希、list列表、set集合、zset有序集合、Bitmaps位图、HyperLogLog、Geo;
2,redis特性:
- 速度快:
- 读10w/s,写8.1w/s;
- 原因:内存存放、C语言实现、单线程无多线程竞争问题;
- 基于键值对构建;
- 功能丰富:
- 键过期功能,实现缓存;
- 发布订阅,实现消息系统;
- Lua脚本,构建新命令;
- 事务,保证事务特性;
- pipeline,减少网络开销;
- 简单稳定:
- 原因:源码少,单线程模型,不需要依赖操作系统类库;
- 客户端语言多:
- 基于tcp协议编程;
- Java、Python、C++……;
- 可持久化:
- RDB和AOF两种方式将数据持久化到硬盘,重启能恢复;
- 主从复制:
- 读写分离;
- 多个数据副本;
- 高可用和分布式:
- 故障发现和自动转移;
- 可扩展;
3,使用场景
- 缓存、排行榜系统、计数器应用、社交网络……
- 中小规模的热数据,不适合大规模的冷数据;
4,启动与关闭相关
-
redis 可执行文件说明
可执行文件 说明 redis-server 启动redis服务 redis-cli 启动redis客户端 redis-benchmark redis基准测试工具 redis-check-aof redis aof 持久化文件检测和修复工具 redis-check-dump redis rdb 持久化文件检测和修复工具 redis-sentinel 启动redis哨兵模式 -
redis 启动
- 默认配置:
- 命令:redis-server;
- 使用默认配置文件:/usr/local/redis-6.2.4/redis.conf;
- 参数启动:
- 命令:redis-server --configKey1 configValue1 --configKey2 configValue2;
- eg:redis-server --port 8888;
- 其他未修改的参数依然使用默认配置文件中的默认参数,且自定义参数不会保存到配置文件中;
- 配置文件启动:
- 命令:redis-server /opt/redis/redis.conf;
- 默认配置:
-
redis 客户端命令
- 交互式:
- 命令:redis-cli -h host -p port;
- 再执行 redis 命令;
- 命令行式:
- 命令:redis-cli -h host -p port commend;
- eg:redis-cli -h 127.0.0.0 -p 6379 get key1;
- 交互式:
-
redis 服务关闭
- redis-cli shutdown nosave|save
- 可以选择是否生成持久化文件;
- 过程:断开与客户端的连接、持久化文件生成、服务关闭;
- kill -9 可能会导致缓冲区资源丢失以及无法生成持久化文件;
二、基本命令
- Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务;
- 命令到服务端后都会进入一个队列,然后被逐一执行;
- 单线程快速原因:
- 纯内存访问;
- 非阻塞io,epoll实现io多路复用;
- 单线程避免了线程切换和竞态产生的消耗;
1,全局命令
| 命令 | 说明 |
|---|---|
| config get name | 查看某个配置信息 |
| config set name value | 在命令行动态设置某个配置信息 |
| config rewrite | 将配置持久化到本地配置文件 |
| info [section] | 查看redis基本情况,或某个section情况 |
| dbsize | 输出key的总数 |
| randomkey | 随机输出一个key |
| keys pattern | 全量遍历键; ·* 代表匹配任意字符; ·?代表匹配一个字符; ·[] 代表匹配部分字符; ·\x 用来做转义; |
| expire key seconds | 设置key过期时间; expire设置毫秒; |
| expireat key timestamp | 键在秒级时间戳timestamp后过期 expireat设置毫秒 |
| object encoding key | 查看key内部结构的编码方式 |
| exists key | 检查key是否存在 |
| del key [key ...] | 删除key |
| ttl/pttl key | 查看key剩余过期时间; pttl表示毫秒级过期时间; -1 表示未设置过期时间; -2 表示key不存在; |
| type key | 查看key的数据结构类型 |
| persist key | 将键的过期时间清除 |
| rename key newkey | 键重命名 重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性 |
| renamenx key newkey | 只有newKey不存在时候才被覆盖 |
| select dbIndex | 切换数据库 |
| flushdb | 清除当前数据库 |
| flushall | 清除所有数据库 |

- key迁移:
- a)move:
- move key dbIndex:用于redis内部迁移,把指定的键从源数据库移动到目标数据库中;
- b)dump+restore
- dump key: 在源Redis上,dump命令会将键值序列化,格式采用的是RDB格式;
- restore key ttl value
- c)migrate
- migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key...]
- ·host:目标Redis的IP地址;
- ·port:目标Redis的端口;
- ·key|""":要迁移的单个键,多个键时为空;
- ·destination-db:目标Redis的数据库索引;
- ·timeout:迁移的超时时间(单位为毫秒);
- ·[copy]:如果添加此选项,迁移后并不删除源键;
- ·[replace]:如果添加此选项,migrate不管目标Redis是否存在该键都会正常迁移进行数据覆盖;
- ·[keys key[key...]]:迁移多个键,eg:“keys key1 key2 key3”;
- migrate命令将dump、restore、del三个命令进行组合,并且具有原子性;
- migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key...]
- a)move:
- key遍历:
- scan cursor [match pattern] [count number]
- ·cursor是一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束;
- ·match pattern是做模式的匹配;
- ·count number表明每次要遍历的键个数,默认值是10;
- 另外还有hscan、sscan、zscan
- 可能有并发问题;
- scan cursor [match pattern] [count number]
2,字符串命令
| 命令 | 说明 |
|---|---|
| setnx | key不存在才设置,可以用于分布式锁 |
| setxx | key存在才设置 |
| append key value | 字符串末尾追加值 |
| strlen key | 返回字符串长度 |
| getset key value | 设置并返回原值 |
| setrange key offeset value | 设置指定位置的字符 |
| getrange key start end | 获取部分字符串,闭区间 |
- 值可以是字符串、数值、二进制,最大不能超过512MB;
- set key value [ex seconds] [px milliseconds] [nx|xx];
- ex seconds:为键设置秒级过期时间;
- px milliseconds:为键设置毫秒级过期时间;
- nx:键必须不存在,才可以设置成功,用于添加;
- xx:键必须存在,才可以设置成功,用于更新;
- 对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视
- setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间。
- mget 相比于多次 get 可以节省网络开销;
- 自增减:incr、incrby、incrbyfloat、decr、decrby;
- 内部编码:
- int:8个字节的长整型;
- embstr:小于等于39个字节的字符串;
- raw:大于39个字节的字符串;
3,哈希命令
| 命令 | 说明 |
|---|---|
| hset key field value | 设置指定字段的值 |
| hget key field | 获取指定字段的值 |
| hmset key field1 value1 [field2 value2 ...] | 同时将多个字段的值 |
| hmget key field1 [field2 ...] | 获取所有给定字段的值 |
| hgetall key | 获取所有字段的值 |
| hkeys key | 获取所有字段 |
| hvals key | 获取所有值 |
| hlen key | 获取字段的数量 |
| hstrlen key field | 获取指定字段的字符串值长度 |
| hdel key field2 [field2 ...] | 删除所有给定的字段 |
| hexists key field | 查看指定字段是否存在 |
| hincrby key field increment | 为指定字段的整数值加上增量 increment |
| hincrbyfloat key field increment | 为指定字段的浮点数值加上增量 increment |
| hsetnx key field value | 只有在字段 field 不存在时,设置哈希表字段的值 |
| hscan key cursor [MATCH pattern] [COUNT count] | 从key的cursor游标开始查询键符合pattern的字段和值,每次查询的数量是count |
- 哈希类型的内部编码:
- ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,在节省内存方面比hashtable更加优秀;
- hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1);
4,列表命令
| 命令 | 说明 |
|---|---|
| lpush key value [value ...] | 从左边插入元素 |
| rpush key value [value ...] | 从右边插入元素 |
| linsert key before/after pivot value | 在pivot前或后插入元素 |
| lrange key start end | 获取指定范围内的元素列表,闭区间,左往右0 |
| lindex key index | 获取列表指定索引下标的元素 |
| llen key | 获取列表长度 |
| lpop key | 从列表左侧弹出元素 |
| rpop key | 从列表右侧弹出 |
| lrem key count value | 删除count数量的指定元素,count>0从左往右,count<0从右往左,count=0全部删除 |
| ltrim key start end | 按照索引范围修剪列表,闭区间 |
| lset key index newValue | 修改指定索引下标的元素 |
| blpop/brpop key [key ...] timeout | 阻塞式弹出 |
- 一个列表最多存储2^32-1个元素;
- 列表类型的内部编码:
- ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用;
- linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现;
- quicklist(快速列表):以一个ziplist为节点的linkedlist,结合了两者的优势,为列表类型提供了一种更为优秀的内部编码实现;
5,集合命令
| 命令 | 说明 |
|---|---|
| sadd key element [element ...] | 添加元素,返回结果为添加成功个数 |
| srem key element [element ...] | 删除元素,返回结果为删除成功个数 |
| scard key | 计算元素个数 |
| sismember key element | 判断元素是否在集合中 |
| smember key | 获取所有元素 |
| srandmember key [count] | 随机从集合返回指定个数元素,不删除元素 |
| spop key | 从集合随机弹出元素,并删除 |
| sinter/suinon/sdiff key [key ...] | 求多个集合的交集、并集、差集 |
| sinterstore/suionstore/sdiffstore destination key [key ...] | 将交集、并集、差集的结果保存 |
- 集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素;
- 一个集合最多存储2^32-1个元素;
- 集合类型的内部编码:
- intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用;
- hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使 用hashtable作为集合的内部实现;
6,有序集合命令
| 命令 | 说明 |
|---|---|
| zadd key score member [score member ...] | 添加成员 ·nx:member必须不存在,才可以设置成功,用于添加; ·xx:member必须存在,才可以设置成功,用于更新; ·ch:返回此次操作后,有序集合元素和分数发生变化的个数; ·incr:对score做增加,相当于zincrby |
| zcard key | 计算成员个数 |
| zscore key member | 计算某个成员的分数 |
| zrank/zrevrank key member | 计算成员的排名,分别是分数从低到高和从高到低 |
| zrem key member [member ...] | 删除成员 |
| zincrby key increment member | 增加成员的分数 |
| zrange/zrevrange key start end [withscores] | 返回指定排名范围的成员,闭区间; withscores选项,同时会返 回成员的分数 |
| zrangebyscore/zrevrangebyscore key max min [withscores] [limit offset count] | 返回指定分数范围的成员; [limit offset count]选项可以限制输出的起始位置和个数; min和max还支持开区间和闭区间,-inf和+inf分别代表无限小和无限大; |
| zcount key min max | 返回指定分数范围成员个数 |
| zremrangebyrank key start end | 删除指定排名内的升序元素 |
| zremrangebyscore key min max | 删除指定分数范围的成员 |
| zinterstore/zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum/min/max] | 交/并集 ·destination:交集计算结果保存到这个键; ·numkeys:需要做交集计算键的个数; ·key[key...]:需要做交集计算的键; ·weights weight[weight...]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,权重默认是1; ·aggregate sum/min/max:计算成员交集后,member的分值可以按照sum(和)、 min(最小值)、max(最大值)做汇总,默认值是sum; |
- 有序集合中的元素可以排序,它给每个元素设置一个分数(score)作为排序的依据;
- 有序集合中的元素不能重复,但是score可以重复;
- 有序集合类型的内部编码:
- ·ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-
entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用;
- ·skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,此时ziplist的读写效率会下降。
- ·ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-
entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用;
三、基本功能
1,慢查询
- 慢查询:
- 就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息记录下来;
- 日志内容:日志id、发生时间戳、命令耗时、执行命令和参数;
- 日志存放在指定长度的先进先出的队列中;
- 慢查询只记录命令执行时间,并不包括命令排队和网络传输时间。
- 配置参数:
- slowlog-log-slower-than:预设阈值;
- slowlog-max-len:日志存储数量;
- 相关命令:
- slowlog get [n]:获取慢查询日志;
- slowlog len:获取慢查询日志列表当前的长度;
- slowlog reset:慢查询日志重置;
2,redis-cli命令
| 参数 | 说明 | 示例 |
|---|---|---|
| -r | (repeat)将命令执行多次 | redis-cli -r 3 ping |
| -i | (interval)每隔几秒执行一次命令,但是必须和-r一起使用 | redis-cli -r 5 -i 1 ping |
| -x | 从标准输入(stdin)读取数据作为redis-cli的最后一个参数 | echo "world" | redis-cli -x set hello |
| -c | (cluster)连接Redis Cluster节点时需要使用的 | - |
| -a | (auth)对于配置密码的redis,无需手动输入auth命令 | |
| --slave | 把当前客户端模拟成当前Redis节点的从节点,可以用来 获取当前Redis节点的更新操作 | - |
| --rdb | 请求Redis实例生成并发送RDB持久化文件,保存在本地 | - |
| --pipe | 将命令封装成Redis通信协议定义的数据格式,批量发送 给Redis执行 | - |
| --bigkeys | 使用scan命令对Redis的键进行采样,从中找到内存占用比 较大的键值,这些键可能是系统的瓶颈 | - |
| --eval | 指定lua脚本 | - |
| --latency | 测试客户端到目标Redis的网络延迟,执行结果只有一条 | redis-cli -h host -p port --latency |
| --latency-history | 分时段了解延迟信息,通过 -i 控制间隔时间 | redis-cli -h host -p port -i 5 --latency-history |
| --latency-dist | 使用统计图表的形式从控制台输出延迟统计信息 | - |
| --stat | 可以实时获取Redis的重要统计信息,包括增量数据 | - |
| --raw和--no-raw | 返回结果是原始格式或格式化后的 | - |
3, redis-server命令
| 参数 | 说明 | 示例 |
|---|---|---|
| --test-memory | 用来检测当前操作系统能否稳定地分配指定容量的内存给 Redis,可以有效避免因为内存问题造成Redis崩溃,单位MB | redis-server --test-memory 1024 |
4,redis-benchmark命令
| 参数 | 说明 | 示例 |
|---|---|---|
| -c | (clients)选项代表客户端的并发数量(默认是50) | - |
| -n | (num)选项代表客户端请求总量(默认是100000) | redis-benchmark -c 100 -n 20000 |
| -q | 显示redis-benchmark的requests per second信息 | - |
| -r | (random)向redis中插入更多随机的键 | -r 1000(表示对后三位随机处理) |
| -P | 每个请求pipeline的数据量(默认为1) | - |
| -k | 选项代表客户端是否使用keepalive,1为使用,0为不使用,默认值为 1 | - |
| -t | 对指定命令进行基准测试 | -t get,set |
| --csv | 将结果按照csv格式输出 | - |
5,原生批命令与pipeline区别
- Redis客户端执行一条命令分的四个过程:发送命令、命令排队、命令执行、返回结果;
- 其中发送和返回,称为Round Trip Time(RTT,往返时间),批命令和pipeline都能节省这部分时间;
- 原生批命令包括:hset、hget、mset、mget……
| 批命令 | pipeline |
|---|---|
| 原子的 | 非原子的 |
| 一个命令对应多个key | 支持多个命令 |
| 服务端支持实现 | 客户端和服务端都共同支持实现 |
6,发布订阅
- 消息发布 者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息;
- 客户端在执行订阅命令之后进入了订阅状态,只能接收subscribe、 psubscribe、unsubscribe、punsubscribe的四个命令;
| 功能 | 命令 |
|---|---|
| 发布消息 | publish channel message |
| 订阅频道 | subscribe channel [channel ...] |
| 取消订阅 | unsubscribe [channel [channel ...]] |
| 按照模式订阅频道 | psubscribe pattern [pattern...] |
| 按照模式取消订阅 | punsubscribe [pattern [pattern ...]] |
| 查看活跃的频道 | pubsub channels [pattern] |
| 查看频道订阅数 | pubsub numsub [channel ...] |
| pubsub numpat |