1.基础知识

1.概述

  • Redis是完全开源免费的,遵守BDD协议,是一个高性能的key-value数据库。

    1.相对于其他key-value DB的特点

  • 1.Redis支持数据持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载数据。
  • 2.Redis不仅仅支持key-value类型的数据,同时还提供了list、set、zset、hash等数据结构的存储
  • 3.Redis支持数据的备份,即master-slave模式的数据备份。

2.优势

  • 性能极高。Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的类型。Redis支持二进制案例的Strings、Lists、Hashes、Sets及Ordered Sets数据类型操作。
  • 原子性。Redis的所有操作都是原子性的,意思就是要么执行成功要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,通过MULTI和EXEC指令包起来。

3.Redis与其他key-value存储有什么不同

  • Redis有着为更为复杂的数据结构并提供原子性操作。
  • Redis运行在内存中但是可以持久化到磁盘,所以在对不同的数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。
  • 相对于磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样redis可以做很多内部复杂性很强的事情。在磁盘方面他们是紧凑的以追加的方式产生的,因此不需要进行随机访问。

2.redis key操作命令

  • 用于管理redis的键

1.语法

1
redis 127.0.0.1:6379> COMMAND KEY_NAME
  • 示例
1
2
3
4
redis 127.0.0.1:6379> SET test test
OK
redis 127.0.0.1:6379> DEL test
(integer) 1

2.Redis keys命令

  • DEL key 该命令用于在key存在时删除key

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 语法
    del key_name

    # 返回值
    被删除 key 的数

    #实例
    redis 127.0.0.1:6379>DEL w3ckey
    (integer) 1
  • DUMP key 序列化给定key,并返回被序列化的值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 语法
    DUMP KEY_NAME

    # 返回值
    如果 key 不存在,那么返回 nil 。 否则,返回序列化之后的值。

    #实例
    redis> DUMP greeting<br/>"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
    redis>DUMP not-exists-key
    (nil)
  • EXISTS key 检查key是否存在

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 语法
    EXISTS KEY_NAME

    # 返回值
    若 key 存在返回 1 ,否则返回 0 。

    # 实例
    redis 127.0.0.1:6379> EXISTS test
    (integer) 0
  • EXPIRE key seconds 为给定 key 设置过期时间,以秒计。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 语法
    Expire KEY_NAME TIME_IN_SECONDS

    # 返回值

    设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。

    # 实例
    redis 127.0.0.1:6379> EXPIRE test 60
    (integer) 1
  • EXPIREAT key timestamp 设置key的过期时间,接受的参数是UNIX时间戳(unix timestamp)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 语法
    redis 127.0.0.1:6379> Expireat KEY_NAME TIME_IN_UNIX_TIMESTAMP

    # 返回值
    设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。

    # 实例
    redis 127.0.0.1:6379> EXPIREAT test 1293840000
    (integer) 1
    redis 127.0.0.1:6379> EXISTS test
    (integer) 0
  • PEXPIRE key milliseconds 设置过期时间 单位是毫秒

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # 语法
    PEXPIRE key_name milliseconds

    # 返回值
    设置成功,返回 1

    key 不存在或设置失败,返回 0

    # 实例
    redis> SET mykey "Hello"
    "OK"
    redis> PEXPIRE mykey 1500
    (integer) 1
    redis> TTL mykey
    (integer) 1
    redis> PTTL mykey
    (integer) 1498
    redis>
  • PEXPIREAT key milliseconds-timestamp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 语法
    redis 127.0.0.1:6379> PEXPIREAT KEY_NAME TIME_IN_MILLISECONDS_IN_UNIX_TIMESTAMP

    # 返回值
    设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。


    # 实例
    redis 127.0.0.1:6379> PEXPIREAT test 1555555555005
    (integer) 1

EXPIREAT key timestamp|EXPIREAT的作用和EXPRIR类型,用于key的设置过期时间。不同在于EXPIREAT命令接受的时间参数是UNIX时间戳(unix timestamp)
PEXPRIE key milliseconds|设置key的过期时间以毫秒计。
KEYS pattern|查找所有符合给定模式(pattern)的key keys * 查看所有的key
MOVE key db|将当前数据库的key移动到给定的数据库DB当中
PERSIST key|移除key的过期时间,key将持久保持。
PTTL key|以毫秒为单位返回key的剩余的过期时间。
TTL key|以秒为单位,返回给定key的剩余生存时间(TTL time to live)
RANDOMKEY|从当前数据库中随机返回一个
RENAME key newkey|修改key的名称
RENDMENX key newkey|仅当newkey不存在时,将key改为newkey
TYPE key|返回key所存储的值的类型。

3.数据类型

  • string(字符串)、hash(哈希)、list(列表)、set(集合)zset(sorted set:有序集合)。

2.string(字符串)

  • string是一个redis最基本的类型,可以理解为Memcached一模一样的类型,一个key对应一个value。
  • string类型是二进制安全的。redis的string可以包含任何数据。比如jpg图片或者序列化的对象。
  • string类型是Redis最基本的数据类型,string类型的值最大能存储512MB。

1.语法

  • 基本语法
    1
    127.0.0.1:6379>COMMAND KEY_NAME
  • 设置一个key为test,value为 test的键值对
    1
    2
    3
    4
    5
    6
    127.0.0.1:6379> set test test
    OK

    // 取出
    127.0.0.1:6379> get test
    "test"

    2.常用命令

    命令|描述
  • |-
    SET key value|设置指定key的值
    GET key|获取指定的key值
    GETRANGE key start end|返回key中字符串值的子字符(截取)
    GETSET key value|将给定key的值设为value,并返回key的旧值(old value)
    GETBIT key offset|将key说存储的字符串子,获取指定偏移量上的位(bit)
    MGET key1[key2…]|获取所有(一个或多个)给定的key的值
    SETBIT key offset value|对key说存储的字符串值,设置或者清楚指定偏移量上的位(bit)
    SETNX key value|只有在key不存在时设置key的值
    SETRANGE key offset value|用value参数覆写给定key所存储的字符串值,从偏移量offset开始。
    STRLEN key|返回key所存储的字符串值的长度
    MSET key value[key value]|同时设置一个或多个key-value对。
    MSETNX key value [key value….]|同时设置一个或者多个key-value对。
    PSETEX key milliseconds value|这个命令和SETEX命令相似,但它以毫秒为单位设置key的生存空间,而不是像SETEX命令那样,以秒为单位。
    INCR key|将key中存储的数字值增1
    INCRBY key increment|将key所存储的值加上给定的增量值(increment)。
    INCRBYFLOAT key increment|将key所存储的值加上给定的浮点增量值(increment)
    DECR key|将key中存储的数字值减一。
    DECRBY key decrement|key所存储的值减去给定的减量值(decrement)。
    APPEND key value|如果key已经存在并且是一个字符串,APPEND命令将指定的value追加到该key原来值(value)的末尾。

2.哈希(Hash)

  • hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
  • redis每个hash可以存储2的32次方 - 1 个键值对(40多亿)

1.示例

1
2
3
4
5
6
7
8
9
10
11
12
13
127.0.0.1:6379> HMSET test2 name 'key' value value
OK
127.0.0.1:6379> HGET test2 name
"key"
127.0.0.1:6379> HMSET hashTest name hashTest value abcd
OK
127.0.0.1:6379> HGETALL hashTest
1) "name"
2) "hashTest"
3) "value"
4) "abcd"
127.0.0.1:6379> HGET hashTest value
"abcd"

2.hash命令

命令 描述
HDEL key field1 [field2]|删除一个或多个哈希表字段

HEXISTS key field|查看哈希表中,指定的key是否存在
HGET key field|获取存储在哈希表中指定字段的值
HGETALL key|获取在哈希表中指定key的所有字段和值
HINCRBY key field increment|为哈希表key中的指定字段的整数值加上增量increment
HINCRBYFLOAT key field increment|为哈希表key中的指定字段的浮点数值加上增量increment
HKEYS key|获取所有哈希表中的字段
HLEN key|获取hash表中的key的数量
HMGET key filed1 [field2….]|获取所有给定字段的值
HMSET key field1 value1 [field2 value2]|同时将多个field-value(域-值)对设置到哈希表key中。
HSET key field value|将哈希表key中的字段field的值设为value
HSETNX key field value|只有在字段不存在时,设置哈希表中的值
HVALS key|获取哈希表中所有值
HSCAN key cursor [MATCH pattern] [COUNT count]|迭代哈希表中的键值对

3.列表(List)

  • Redis列表是简单的字符串列表,按照插入顺序排序。
  • 可以添加一个元素到列表的头部(左边)或者尾部(右边)
  • 一个列表最多包含2的32次方-1个元素(4294967295, 每个列表超过40亿个元素)

1.示例

  • testList 插入key为testList的三个值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    127.0.0.1:6379> lpush testList test1
    (integer) 1
    127.0.0.1:6379> lpush testList test2
    (integer) 2
    127.0.0.1:6379> lpush testList test3
    (integer) 3
    127.0.0.1:6379> LRANGE testList 0 10
    1) "test3"
    2) "test2"
    3) "test1"

2.列表相关命令

命令 描述
BLPOP key1 [key2] timeout|移出并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出的元素为止

BRPOP key1 [key2] timeout|移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或者发现可弹出元素为止
BRPOPLPUSH source destination timeout|从列表中弹出一个值,将弹出的元素插入到另一个列表并返回它;如果列表没有元素会阻塞列表直到等待超时或发现可弹出的元素为止。
LINDEX key index|通过索引获取列表的元素
LINSERT key BEFORE|AFTER pivot value|在列表的元素前或者后插入元素
LLEN key|获取列表的长度
LPOP key|移除并获取列表的第一个元素
LPUSH key value1[value2]|将一个或者多个值插入到列表的头部
LPUSHX key value|将一个值插入到已存在的列表头部
LRANGE key start stop|获取列表指定范围内的元素
LREM key count value|移除列表元素
LSET key index value|通过索引设置列表元素的值
LTRIM key start stop|对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
RPOP key|移除列表最后一个元素,并返回
RPOPLPUSH source destination|移除列表的最后一个元素,并将该元素添加到另一个列表并返回
RPUSH key value1 [value2]|在列表中添加一个或多个值
RPUSHX key value|为已存在的列表添加值

4.集合(Set)

  • Set是string类型的无序组合。
  • Set成员是唯一的,不能出现重复值。
  • Set是通过hash实现的,所以添加、删除、查找的复杂度都是O(1)
  • Set中最大的成员数为2的三十二次方-1(4294967295, 每个集合可存储40多亿个成员)

1.示例

  • 添加key为test的若干值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    127.0.0.1:6379> SADD test 1
    (integer) 1
    127.0.0.1:6379> SADD test 2
    (integer) 1
    127.0.0.1:6379> SADD test 3
    (integer) 1
    127.0.0.1:6379> SADD test 4
    (integer) 1
    127.0.0.1:6379> SMEMBERS test
    1) "1"
    2) "2"
    3) "3"
    4) "4"

    2.Set命令

    命令|描述
  • |-
    SADD key member1 [member2]|向集合添加一个或多个成员
    SCARD key|获取集合的成员数
    SDIFF key1 [key2]|返回给定所有集合的差集
    SDIFFSTORE destination key1 [key2]|返回给定所有集合的差集并存储在destination中
    SINTER key1 [key2]|返回给定所有集合的交集
    SINTERSTORE destination key1 [key2]|返回给定所有集合的交集并存储在destination中
    SISMEMEBER key member|判断member元素是否是集合key的成员
    SMEMBERS key|返回集合中所有成员
    SMOVE source destination member|将member元素从source集合移动到destination集合
    SPOP key|移除并返回集合中的一个随机元素
    SRANDMEMBER key [count]|返回集合中一个或多个成员
    SUNION key1 [key2]|返回所有给定集合的并集
    SUNIONSTORE destination key1 [key2]|所有给定集合的并集存储在destination 集合中
    SSCAN key cursor [MATCH pattern] [COUNT count]|迭代集合中的元素

5.有序集合(sorted set)

  • redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
  • 不同得是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
  • 有序集合的成员是唯一的,但是分数(score)却可以重复
  • 集合是通过哈希表实现的,所有添加删除查找都是O(1)。
  • 有序集合最大的成员数为2的三十二次方-1(4294967295, 每个集合可存储40多亿个成员)

1.示例

  • 通过ZADD向redis有序集合中添加三个值并关联分数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    127.0.0.1:6379> zadd test 1 test1
    (integer) 1
    127.0.0.1:6379> zadd test 2 test2
    (integer) 1
    127.0.0.1:6379> zadd test 3 test3
    (integer) 1
    127.0.0.1:6379> zadd test 4 test4
    (integer) 1
    127.0.0.1:6379> zrange test 0 10 withscores
    1) "test1"
    2) "1"
    3) "test2"
    4) "2"
    5) "test3"
    6) "3"
    7) "test4"
    8) "4"

    2.redis有序集合命令

    命令|描述
  • |-
    ZADD key score1 member1 [score2 member2]|向有序集合添加一个或多个成员,或者更新已存在成员的分数
    ZCARD key|获取有序集合的成员数
    ZCOUNT key min max|计算在有序集合中指定区间分数的成员数
    ZINCRBY key increment member|有序集合中对指定成员的分数加上增量increment
    ZINETERSTORE destination numkeys key [key …]|计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合key中
    ZLEXCOUNT key min max|在有序集合中指定字典区间内成员数量
    ZRANGE key start stop [WITHSCORES]|通过索引区间返回有序集合指定区间内的成员
    ZRANGEBYLEX key min max [LIMIT offset count]|通过字典区间返回有序集合的成员
    ZRANGEBYSCORE key min max [WITHSCORES][LIMIT]|通过分数返回有序集合指定区间内的成员
    ZRANK key member|返回有序集合中指定成员的索引
    ZREM key member[member…]|移除有序集合中的一个或多个成员
    ZREMRANGEBYLEX key min max|移除有序集合中给定的字典区间的所有成员
    ZREMRANGEBYRANK key start stop|移除有序集合中给定的排名区间的所有成员
    ZREMRANGEBYSCORE key min max|移除有序集合中给定的分数区间的所有成员
    ZREVRANGE key start stop [WITHSCORES]|返回有序集合中指定区间内的成员,通过索引,分数从高到低
    ZREVRANGEBYSCORE key max min [WITHSCORES]|返回有序集合中指定分数区间内的成员,分数从高到低排序
    ZREVRANK key member|返回有序集合中指定成员的排名,有序集合按分数值递减(从大到小)排序
    ZSCORE key member|返回有序集合中,成员的分数值
    ZUNIONSTORE destination numkeys key [key…]|计算给定的一个或者多个有序集的并集,并存储在新的key中
    ZSCAN key cursor [MATCH pattern][COUNT cout]|迭代有序集合中的元素(包含元素成员和元素分值)

4.HyperLogLog

  • 2.8.9添加了HyperLogLog结构
  • 用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
  • 每个HyperLogLog键只需要花费12kb内存,就可以计算出接近2^64个不同元素的基数。这和计算基数时,元素越多消耗内存就越多形成鲜明对比。
  • 因为HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,所以HyperLogLog不像集合那样,返回输入的各个元素。

1.什么是基数

  • 比如数据集{1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集为{1, 3, 5 ,7, 8}, 基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速基数。

2.示例

  • 工作过程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    127.0.0.1:6379> PFADD test test1
    (integer) 1
    127.0.0.1:6379> PFADD test test2
    (integer) 1
    127.0.0.1:6379> PFADD test test3
    (integer) 1
    127.0.0.1:6379> PFADD test test4
    (integer) 1
    127.0.0.1:6379> PFCOUNT test
    (integer) 4

3.HyperLogLog命令

命令 描述
PFADD key element [element…] 添加指定元素到HyperLogLog中
PFCOUNT key [key…] 返回给定HyperLogLog的基数估算值
PFMERGE destkey sourcekey [sourcekey…] 将多个HyperLogLog合并为一个HyperLogLog

5.发布订阅

  • 发布订阅(pub/sub)是一种消息通信模式:发布者(pub)发送消息,订阅着(sub)接受消息。

  • 可以订阅任意数量的频道

  • 下图展示了频道channel1,以及订阅这个频道的三个客户端–client2、client5和client1之间的关系

  • 当有新消息时PUBLISH命令发送给频道channel1时,这个消息会被发送给订阅它的三个客户端

1.示例

  • 创建名为redisChat的频道
    1
    2
    3
    4
    5
    6
    redis 127.0.0.1:6379> SUBSCRIBE redisChat

    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "redisChat"
    3) (integer) 1
  • 重新开启一个新redis客户端,然后在同一个频道redisChat发布消息,订阅着则能收到消息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

    (integer) 1

    redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"

    (integer) 1

    # 订阅者的客户端会显示如下消息
    1) "message"
    2) "redisChat"
    3) "Redis is a great caching technique"
    1) "message"
    2) "redisChat"
    3) "Learn redis by runoob.com"

    2.发布订阅命令

    命令|描述
  • |-
    PSUBSCRIBE pattern [pattern…]|订阅一个或者多个符合给定模式的频道
    PUBSUB subcommand [argument [argument…]]|查看订阅与发布系统状态
    PUBLISH channel message|将消息发送到指定的频道
    PUNSUBSCRIBE [pattern [pattern…]]|退订所有给定模式的频道
    SUBSCRIBE channel [channel…]|订阅给定的一个或者多个频道的信息
    UNSUBSCRIBE [channel [channel…]]|退订指定的频道

6.事务

  • redis事务可以再一次执行多个命令,并带有是哪个重要的保证

    • 批量操作在放松exec命令前被放入队列缓存
    • 受到exec命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
    • 在事务执行过程中,其他客户端提交的命令请求不会插入到事务执行命令序列中。
  • 一个事务从开始到执行要经历三个阶段

    • 开始事务
    • 命令入队
    • 执行事务

1.示例

  • MULTI开始一个事务,然后将多个命令入队到事务中,最后由EXEC命令触发事务,一并执行事务中的所有命令
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set test1 'test1'
    QUEUED
    127.0.0.1:6379> get test1
    QUEUED
    127.0.0.1:6379> sadd tag 'test2' 'test3' 'test4'
    QUEUED
    127.0.0.1:6379> smembers tag
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) "test1"
    3) (integer) 3
    4) 1) "test4"
    2) "test3"
    3) "test2"
  • 单个redis命令执行是原子性的,但redis没有在事务上增加任何原子性的机制,所以redis事务的执行并不是原子性的。
  • 事务可以理解我一个打包的批量执行脚本,但批量指令并非原子化操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不执行。

2.事务命令

命令 描述
discard|取消事务,放弃执行事务块内的所有命令

exec|执行一个事务块内的命令
multi|标记一个事务块的开始。
unwatch|取消watch命令对所有key的监视
watch key [key…]|监视一个或者多个key,如果在事务执行之前这个或这些key被其他命令说改动,那么事务将被打断。

7.redis脚本

  • redis脚本使用Lua解释器来执行脚本
  • 执行脚本的常用命令为EVAl

1.语法

1
redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]

2.示例

1
2
3
4
5
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

3.Redis脚本命令

命令 描述
eval script numberkeys key [key...] arg[arg...]|执行Lua脚本

evalsha sha1 numberkeys key [key…] arg[arg…]|执行Lua脚本
script exists script [script…]|查看指定的脚本是否已经被保存在缓存当中
script flush|从脚本缓存中移除所有脚本
script kill|杀死当前正在运行的Lua脚本
script load script|将脚本添加到缓存中,但并不立即执行这个脚本

8.redis连接

  • redis连接命令主要是用于连接redis服务

1.示例

  • 通过密码验证连接到redis服务,并检测是否在运行
    1
    2
    3
    4
    redis 127.0.0.1:6379> AUTH "password"
    OK
    redis 127.0.0.1:6379> PING
    PONG

2.redis命令

命令 描述
auth password|验证密码是否正确

echo message|打印字符串
ping|查看服务是否在运行
quit|关闭当前连接
select index|切换到指定的数据库

9.redis服务器

  • 用于管理redis服务

1.示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
127.0.0.1:6379> info
# Server
redis_version:4.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:9bdfa9da9a573135
redis_mode:standalone
os:Darwin 18.7.0 x86_64
arch_bits:64
multiplexing_api:kqueue
atomicvar_api:atomic-builtin
gcc_version:4.2.1
process_id:3839
run_id:47fe5d4b2196473360f16da82b0798e534bc0956
tcp_port:6379
uptime_in_seconds:78567
uptime_in_days:0
hz:10
lru_clock:12653746
executable:/Users/mengxiangcun/yingEDU/backstage_test/redis-server
config_file:

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:1027728
used_memory_human:1003.64K
used_memory_rss:520192
used_memory_rss_human:508.00K
used_memory_peak:1027728
used_memory_peak_human:1003.64K
used_memory_peak_perc:100.09%
used_memory_overhead:1013502
used_memory_startup:963760
used_memory_dataset:14226
used_memory_dataset_perc:22.24%
total_system_memory:8589934592
total_system_memory_human:8.00G
used_memory_lua:40960
used_memory_lua_human:40.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:0.51
mem_allocator:libc
active_defrag_running:0
lazyfree_pending_objects:0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1572859868
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

# Stats
total_connections_received:2
total_commands_processed:9
instantaneous_ops_per_sec:0
total_net_input_bytes:330
total_net_output_bytes:20475
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:2
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:1117
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Replication
role:master
connected_slaves:0
master_replid:a7fbc1a80cdfe57c81576aaed9fe37fe59ae2466
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:10.22
used_cpu_user:4.71
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=2,expires=0,avg_ttl=0

2.redis服务器命令

命令 描述
bgrewriteaof 异步执行一个AOF(AppendOnly File)文件重写操作
bgsave 在后台异步保存当前数据库的数据到磁盘
client kill [ip:port] [ID client-id] 关闭客户端连接
client list 获取连接到服务器的客户端连接列表
client getname 获取连接的名称
client pause timeout 在指定时间内终止运行来自客户端的命令
client setname connection-name 设置当前连接的名称
cluster slots 获取集群节点的映射数组
command 获取redis命令详情数组
command count 获取Redis命令总数
command getkeys 获取给定命令的所有键
time 返回当前服务器时间
command info command-name [command-name…] 获取指定redis命令描述的数组
connfig get parameter 获取指定配置参数的值
config rewrite 对启动redis服务器时所指定的redis.conf配置文件进行改写
config set parameter value 修改redis配置参数,无需重启
config resetstat 重置info命令中某些统计数据
dbsize 返回当前数据库key的数量
debug object key 获取key的调试信息
debug segfault 让redis崩溃
fulushall 删除所有数据库的所有key
flushdb 删除当前数据库中的所有key
info [section] 获取redis服务器的各种信息和统计数值
lastave 返回最近一次redis成功将数据保存到磁盘三的时间,以unix时间戳格式表示
monitor 实时打印redis服务器接收到的命令,调试用
role 返回主从实例所有的角色
save 同步保存数据到硬盘
shutdown [nosave] [save] 异步保存数据到硬盘,并关闭服务器
slaveof host port 将当前服务器转变为指定服务器的从属服务器(slave server)
slowlog subcommand [argument] 管理redis的慢日志
sync 用于复制功能(replication)的内部命令

10.Redis数据备份与恢复

  • Redis save命令用于创建当前数据库的备份

1.语法

1
2
3
127.0.0.1:6379> save
11677:M 20 Nov 16:14:53.774 * DB saved on disk
OK

2.恢复数据

  • 如果需要恢复数据,只需将备份文件(dump.rdb)移动到redis安装目录并启动即可。
  • 获取redis目录
    1
    2
    3
    127.0.0.1:6379> config get dir
    1) "dir"
    2) "/usr/local/redis/bin"

3.备份数据的另一种方法

  • 创建redis备份文件可以使用bgsave,该命令是后台运行的
    1
    2
    3
    127.0.0.1:6379> BGSAVE

    Background saving started

11.redis安全

  • 通过redis的配置文件设置密码参数,这样客户端连接到redis服务就需要密码验证,这样可以让redis更安全

1.语法

  • 1.查看是否设置密码验证,如果requirepass为空,这就意味着无需密码可以连接到redis服务

    1
    2
    3
    127.0.0.1:6379> config get requirepass
    1) "requirepass"
    2) ""
  • 2.修改密码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    127.0.0.1:6379> CONFIG set requirepass "test"
    OK
    # 这里需要重新链接后才可以查看
    # 但是如果关闭server再启动就会恢复到没有密码的状态
    # 所以最好是修改配置文件
    # 链接
    redis-cli -p 6379 -a test -h 127.0.0.1

    127.0.0.1:6379> CONFIG get requirepass
    1) "requirepass"
    2) "test"

2.实例

  • 1.可以使用auth命令
    1
    2
    3
    4
    5
    6
    7
    8
    # 连接
    redis-cli

    127.0.0.1:6379> set 1 1
    OK
    127.0.0.1:6379> get 1
    "1"

    12.redis性能测试

  • redis性能测试是通过同时执行多个命令实现的。

    1.语法

  • 该命令是在redis的目录下执行的,而不是redis客户端的内部命令
    1
    redis-benchmark [option] [option value]

2.实例

  • 1.指定10000个请求数,测试完成后退出
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    redis-benchmark -n 10000 -q

    PING_INLINE: 64102.56 requests per second
    PING_BULK: 75187.97 requests per second
    SET: 79365.08 requests per second
    GET: 75187.97 requests per second
    INCR: 84033.61 requests per second
    LPUSH: 83333.34 requests per second
    RPUSH: 84033.61 requests per second
    LPOP: 78740.16 requests per second
    RPOP: 75187.97 requests per second
    SADD: 87719.30 requests per second
    HSET: 86956.52 requests per second
    SPOP: 81967.21 requests per second
    LPUSH (needed to benchmark LRANGE): 85470.09 requests per second
    LRANGE_100 (first 100 elements): 20040.08 requests per second
    LRANGE_300 (first 300 elements): 7153.08 requests per second
    LRANGE_500 (first 450 elements): 5428.88 requests per second
    LRANGE_600 (first 600 elements): 4894.76 requests per second
    MSET (10 keys): 61349.69 requests per second
  • 指定地址、端口、执行set,lpush,请求数10000,通过-q参数让结果只显示每秒执行的请求数
    1
    2
    3
    4
    5
    redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q


    SET: 146198.83 requests per second
    LPUSH: 145560.41 requests per second

3.redis性能测试工具可选参数

选项 描述 默认值
-h|指定服务器主机名|127.0.0.1

-p|指定服务器端口|6379
-s|指定服务器socket|
-c|指定兵法连接数|50
-n|指定请求数|10000
-d|以直接的形式指定SET/GET值的数据大小|2
-k|1=keep alive 0=reconnect|1
-r|SET/GET/INCR使用随机key,SADD随机值|
-P|通过管道传输请求|1
-q|强制退出redis。仅显示query/sec值
–csv|以CSV格式输出
-l|生成循环,永久执行测试
-t|仅运行以逗号分割的测试命令列表。
-I|Idle模式。仅打开N个idle连接并等待。

13.Redis客户端连接

  • redis通过监听一个TCP端口或者Unix socket的方式来接收来自客户端的连接,当一个连接建立后,会执行下列操作
  • 1.客户端socket会被设置为非阻塞模式,因为redis在网络事件处理上采用的是非阻塞多路复用模型。
  • 2.为这个socket设置TCP_NODELAY属性,禁用Nagle算法
  • 3.创建一个可读的文件事件用于监听这个客户端socket的数据发送。

1.最大连接数

  • redis2.4中,最大连接数是被直接硬编码在代码里面,而在2.6版本中这个值编程可配置的。
  • maxclients的默认值是10000,可以在redis.config中进行修改
    1
    2
    3
    127.0.0.1:6379> config get maxclients
    1) "maxclients"
    2) "10000"

    2.实例

  • 1.设置最大连接数100000
    1
    redis-server --maxclients 100000

3.客户端命令

命令|描述
client list|返回连接到redis服务的客户端列表
client setname|设置当前连接的名称
client getname|获取通过client setname命令设置的服务名称
client pause|挂起客户端连接,指定挂起的时间以毫秒计
client kill|关闭客户端连接

14.redis管道技术

  • redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。意味着通常情况下一个请求会遵循以下步骤
  • 1.客户端向服务器发送一个查询请求,并监听socket返回,通常是以阻塞模式,等待服务端响应。
  • 2.服务端处理命令,并将结果返回给客户端

1.redis管道技术

  • redis管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

2.实例

  • 查看redis管道,只需要启动redis实例并输入以下命令
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 使用PING命令查看redis服务是否可用,之后设置test的值为test,然后获取test的值并使用vistor自增3次。
    # 返回的结果中可以看到这些命令一次呢向redis提交,并最终一次性读取所有服务端的响应

    (echo -en "PING\r\n SET test test\r\nGET test\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) |nc localhost 6379

    +PONG
    +OK
    $4
    test
    :1
    :2
    :3

3.管道技术的优势

  • 管道技术最显著的优势是提高了redis服务的性能
  • 下面的测试使用Ruby客户端,支持管道技术特性,测试管道技术对速度的提升效果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    require 'rubygems' 
    require 'redis'
    def bench(descr)
    start = Time.now
    yield
    puts "#{descr} #{Time.now-start} seconds"
    end
    def without_pipelining
    r = Redis.new
    10000.times {
    r.ping
    }
    end
    def with_pipelining
    r = Redis.new
    r.pipelined {
    10000.times {
    r.ping
    }
    }
    end
    bench("without pipelining") {
    without_pipelining
    }
    bench("with pipelining") {
    with_pipelining
    }

    # 结果 开启管道后往返延时更加低
    without pipelining 1.185238 seconds
    with pipelining 0.250783 seconds

    15.Redis分区

  • 分区是分割数据到多个redis实例的处理过程,因此每个实例只保存key的一个子集

1.分区的优势

  • 利用多台计算机的内存和硬盘,可以组建成更大的数据库
  • 利用多核和多台计算机,可以扩展计算能力,利用多台计算和网络适配器,扩展网络带宽。

2.分区不足

  • 1.涉及多个key的操作通常不支持。举例:当两个set映射到不同的redis实例上时,不能对这两个set进行交集操作。
  • 2.涉及多个key的redis事务不能使用。
  • 3.当使用分区时,数据处理较为复杂,比如你需要处理多个rdb/aof文件,并且从多个实例和主机备份持久化文件。
  • 4.增加或删除容量也比较复杂。redis集群大多数支持在运行时添加、删除节点的透明数据平衡能力,但是类似与客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做presharding的技术对此是有帮助的。

3.分区类型

  • 两种类型分区。假设有4个Redis实例R0,R1,R2,R3和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同的方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个redis服务。

1.范围分区

  • 最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。
  • 比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
  • 这种方式是可行的,并且在实际中使用,不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。

2.哈希分区

  • 这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:
  • 1.用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。
  • 2.对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。

2.应用

1.Keyspace Notifications 当键到期、键删除时触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
'use strict';

const redis = require('ioredis');
const redisConfig = require('../config/redis_config');
const EXPIRETIME = 10;

/**
* 添加key
* @param key
* @param value
*/
const client = new redis(redisConfig);

/**
* 添加key
* @param key
* @param value
*/
const addKey = (key, value) => {
client.set(key, JSON.stringify(value), 'EX', EXPIRETIME);
// client.expire(key, EXPIRETIME);
};
/**
* 监听redis过期key
*/
const subscribeExpired = (bot) => {
const sub = new redis(redisConfig);

const expiredSubKey = `__keyevent@${redisConfig.db}__:expired`;

sub.subscribe(expiredSubKey, () => {
console.log('监听开始');
sub.on('message', (info, msg) => {
bot.deleteMessage(-1001329399510, msg);
console.log('key:', msg);
});
});
};
/**
* 初始化监听redis
*/
const initRedisSub = (bot) => {
client.send_command('config', ['set', 'notify-keyspace-events', 'Ex'], subscribeExpired(bot));
};
module.exports = {
addKey,
initRedisSub
};

2.基本操作

1.添加key value

1
set key value

2.添加自动过期key value

1
2
3
set key value ex  seconds

setex key <seconds> value
  • 类似于
    1
    2
    set key value
    expire key second

    3.查看剩余生存时间

    1
    TTL key

4.删除key

1
del key_name

如有侵权行为,请点击这里联系我删除

如发现疑问或者错误点击反馈

备注