[关闭]
@dungan 2020-03-28T03:30:53.000000Z 字数 9386 阅读 101

Redis

Redis 基础

安装与配置

安装

linux 上的安装

  1. $ wget http://download.redis.io/releases/redis-5.0.2.tar.gz
  2. $ tar xzf redis-5.0.2.tar.gz -C /usr/local/
  3. $ cd /usr/local/redis-5.0.2
  4. $ make

编译的二进制文件位于 src 目录

  1. $ cd src
  2. $ redis-server

测试

  1. $ src/redis-cli
  2. redis> set foo bar
  3. OK
  4. redis> get foo
  5. "bar"

这样 redis 就安装成功了。

配置文件

redis 的配置文件位于文件redis安装目录下的 redis.conf 中,下面两个命令可以操作配置项

  1. # CONFIG GET config_key:读取配置项
  2. CONFIG GET *
  3. # CONFIG SET config_key config_value : 设置配置项
  4. CONFIG SET loglevel "notice"

还可以直接通过命令行传递Redis配置参数

  1. redis-server --port 6380 --slaveof 127.0.0.1 6379

通过命令行传递的配置参数的格式和在redis.conf中设置的配置参数格式完全一样, 唯一不同的是需要在关键字之前加上前缀 --。

配置项说明

  • save seconds changes : 即快照方式,指定在多少秒内,有多少次更新操作,就将数据同步到数据文件。
  • rdbcompression yes:指定存储至本地数据库时是否压缩数据,默认为yes。
  • dbfilename dump.rdb:指本地数据库文件名,默认值为dump.rdb。
  • dir:数据库存放的目录。
  • slaveof masterip masterport : 设置当本机为slave服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步。
  • masterauth master-password:当master服务设置了密码保护时,slav服务连接master的密码。
  • requirepass your-passwd:如果配置了连接密码,客户端在连接Redis时需要通过 AUTH password 命令提供密码,默认关闭。
  • maxclients 128: 设置同一时间最大客户端连接数,如果设置 maxclients 0,表示不作限制。
  • maxmemory bytes:指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key。
  • appendonly no:即 AOF,设置是否在每次更新操作后进行日志记录,默认为no。
    • Redis 默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。
  • appendfilename appendonly.aof : 指定更新日志文件名,默认为appendonly.aof。
  • appendfsync everysec: 指定更新日志条件,共有3个可选值:
    • no:表示等操作系统进行数据缓存同步到磁盘(快)。
    • always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)。
    • everysec:表示每秒同步一次(折中,默认值) 。
  • include /path/to/local.conf:指定包含其它的配置文件,常用在多实例场景中载入一些个性化配置。

redis 管理

键值相关命令

DEL key : 在 key 存在时删除 key,不存在的 key 会被忽略。

DUMP key :序列化给定 key。

EXISTS key:检查给定 key 是否存在。

EXPIRE key seconds:设置 key 过多少秒后失效。

PEXPIRE key milliseconds:设置 key 过多少毫秒后失效。

EXPIREAT key timestamp :设置到某个时间点失效, 时间参数是 UNIX 时间戳 。

PEXPIREAT key milliseconds-timestamp:设置到某个时间点失效, 时间参数以毫秒计。

KEYS pattern:查找所有符合给定模式( pattern)的 key,获取 redis 中所有的 key 可用使用 *。

MOVE key db_index:将当前数据库的 key 移动到给定的数据库 db 当中。

PERSIST key:移除 key 的过期时间,key 将持久保持。

PTTL key:以毫秒为单位返回 key 的剩余的过期时间。

TTL key:以秒为单位返回 key 的剩余的过期时间。

RANDOMKEY:从当前数据库中随机返回一个 key 。

RENAME key newkey : 修改 key 的名称。

RENAMENX key newkey : 仅当 newkey 不存在时,将 key 改名为 newkey 。

TYPE key : 返回 key 所储存的值的类型,类型有: none (key不存在),string (字符串),list (列表),set(集合) ,zset (有序集),hash (哈希表)。

服务器相关命令

AUTH:密码认证,如果在 redis.conf 设置了密码,那么连接 redis 后,就需要密码认证。

BGREWRITEAOF:执行一个异步 AOF 文件重写操作。重写会创建一个当前 AOF 文件 的体积优化版本 (appendonly.aof)。

BGSAVE:执行一个异步保存操作,将所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。

SAVE: 执行一个同步保存操作,将所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。

SHUTDOWN [NOSAVE] [SAVE]:异步保存数据到硬盘,并关闭服务器。

CLUSTER SLOTS:当前的集群状态,以数组形式展示。

COMMAND: 返回所有的Redis命令的详细信息,以数组形式展示。

COMMAND INFO command-name [command-name ...]:获取 redis 命令的详细信息。

COMMAND COUNT : 获取 Redis 命令总数。

COMMAND GETKEYS: 用于获取所有 key。

TIME: 获取当前服务器时间(unix时间戳)。

CONFIG GET parameter:获取指定配置参数的值。

CONFIG SET parameter value:设置 redis 配置参数,不会写入配置文件,重启 redis 后会失效。

CONFIG REWRITE:将 CONFIG SET 修改的配置写入到配置文件。

SELECT index:切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。

DBSIZE:获取当前数据库的 key 的数量。

DEBUG OBJECT key:获取 key 的调试信息。

DEBUG SEGFAULT:执行一个非法的内存访问从而让 Redis 崩溃,仅在开发时用于 BUG 调试。

FLUSHALL: 清空整个 Redis 服务器的数据,所有数据库的 key 会被删除。

FLUSHDB:删除当前数据库的所有key。

INFO section:获取 redis 服务器的统计信息,可选参数 section 可以让命令只返回某一部分的信息。

LASTSAVE:返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。

MONITOR:实时监控 Redis 服务器收到的命令,调试用。

ECHO message:打印字符串

PING:查看服务是否运行,如果服务器运作正常的话,会返回一个PONG,通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值。

ROLE : 查看主从架构中当前实例所属的角色,角色有master, slave, sentinel; 返回一个数组, 第一个参数是 master,slave,sentinel 三个中的一个。

SLAVEOF host port: 将当前服务器转变为指定服务器的从属服务器(slave server)。

另外:对一个从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能, 并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。

SYNC:同步主从服务器。

CONFIG RESETSTAT : 重置 INFO 命令中的某些统计数据。

CLIENT LIST : 返回连接到 redis 服务的客户端列表。

CLIENT SETNAME: 设置当前连接的名称。

CLIENT GETNAME: 获取通过 CLIENT SETNAME 命令设置的服务名称。

CLIENT PAUSE timeout : 挂起客户端连接,指定挂起的时间以毫秒计。

CLIENT KILL ip:port : 关闭客户端连接。

QUIT : 关闭与当前客户端与redis服务的连接。

数据结构

String

SET key value : 设置key的值。

GET key : 获取key的值。

GETRANGE key start end : 截取字符(包括 start 和 end 在内),第一个是0。

SETBIT key offset value : 设置二进制数据指定位移处(offset)的值,由于采用二进制格式计数,所以value只能是 0 或 1,该数据结构常用在 key 为非此即彼的一些场景。

例如一个班级假设有30个人每天要打卡,那么对于编号为5的同学,如果他打了卡我们就可以这样记录: SETBIT class 5 1,如果编号为6的同学没打卡,他就是: SETBIT class 6 0。

GETBIT key offset : 获取 key 指定位移处的数据。

GETSET key value : 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

MSET key value [key value ...] : 同时设置一个或多个 key-value 对。

MGET key1 [key2..] : 同时获取多个 key 的值。

SETEX key seconds value : 设置一个有过期时间的key,以秒为单位。

PSETEX key milliseconds value : 和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间。

SETNX key value : 只有在 key 不存在时设置 key 的值; 设置成功返回 1,设置失败返回 0 。

MSETNX key value [key value ...] :同时设置一个或多个 key-value 对,只有 key 不存在时才能设置成功。

SETRANGE key offset value : 替换从 offset 开始之后的字符。

STRLEN key:获取 key 所储存的字符串值的长度。

INCR key:将 key 中储存的数字值增一。

INCRBY key increment:将 key 所储存的值加上给定的增量值(increment)。

INCRBYFLOAT key increment:将 key 所储存的值加上给定的浮点增量值(increment)。

DECR key : 将 key 中储存的数字值减一。

DECRBY key decrement:key 所储存的值减去给定的减量值(decrement)。

APPEND key value:字符串拼接,将 value 拼接到 key 存储的值后面。

Hash

hash特别适合用于存储对象。

HSET key field value : 将哈希表 key 中的字段 field 的值设为 value 。

HGET key field : 获取存储在哈希表中指定字段的值。

HMSET key field1 value1 [field2 value2 ] :同时将多个 field-value 对设置到哈希表 key 中。

HMGET key field1 [field2] : 获取所有给定字段的值。

HGETALL key : 获取在哈希表中指定 key 的所有字段和值。

HSETNX key field value : 只有在字段 field 不存在时,设置哈希表字段的值。

HDEL key field1 [field2] : 删除一个或多个哈希表字段。

HEXISTS key field : 查看哈希表 key 中指定的字段是否存在。

HINCRBY key field increment : 为哈希表 key 中的指定字段的整数值加上增量 increment。

HINCRBYFLOAT key field increment : 为哈希表 key 中的指定字段的浮点数值加上增量 increment。

HKEYS key : 获取所有哈希表中的字段。

HVALS key : 获取哈希表中所有值。

HSCAN key cursor [MATCH pattern] [COUNT count] : 迭代哈希表中的键值对,类似 SCAN 命令。

List

LPUSH key value1 [value2] : 将一个或多个值插入到列表头部。

LPOP key : 移出并获取列表的第一个元素。

RPUSH key value1 [value2] : 用于将一个或多个值插入到列表的尾部。

RPOP key : 移除列表的最后一个元素,返回值为移除的元素。

LPUSHX key value : 将一个或多个值插入到已存在的列表头部,列表不存在时操作无效。

RPUSHX key value : 将一个或多个值插入到已存在的列表尾部,如果列表不存在时操作无效。

BLPOP key1 [key2 ] timeout : 移出并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止,参数设为 0 表示阻塞时间可以无限期延长。

BRPOP key1 [key2 ] timeout : 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

BRPOPLPUSH source destination timeout : 从列表中弹出一个值,将弹出的元素插入到另外一个列表 中并返回它;如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

RPOPLPUSH source destination : 移除列表的最后一个元素,并将该元素添加到另一个列表并返回

LINDEX key index : 通过索引获取列表中的元素。

LINSERT key BEFORE|AFTER element value : 在列表的元素前或者后插入元素。当指定元素不存在于列表中时,不执行任何操作。

LLEN key : 获取列表长度。

LRANGE key start stop : 获取列表指定范围内的元素(含start和st), 0 表示第一个元素,-1表示最后一个元素,LRANGE key 0 0 表示获取第一个元素。

LREM key count value : 移除 count 个值等于 value 的元素。

count > 0 : 从表头开始向表尾搜索,移除 count 个值等于 value 的元素 。
count < 0 : 从表尾开始向表头搜索,移除 count 个值等于 value 的元素 。
count = 0 : 移除列表中所有与 VALUE 相等的值。

LSET key index value : 通过索引设置列表元素的值。

LTRIM key start stop : 裁剪列表(含start和stop)。

为什么要有 BLPOP/BRPOP 之类的阻塞命令?

这是因为有时候客户端为了等待一个新元素到达数据中,需要使用轮询的方式对数据进行探查,但轮询会导致一直占用服务器的资源,因此redis提供了阻塞命令:

在新元素到达时立即进行处理,而新元素还没到达时,就一直阻塞住客户端,避免轮询占用资源。

既然 redis 是单线程的,那么 redis 是如何实现 BLPOP/BRPOP 这类阻塞命令的?

redis 实现了一套事件触发模型,主要处理两种事件:I/O事件(文件事件)和定时事件。而处理它们的就靠一个EventLoop线程,在IO循环中,完成客户端连接应答、命令请求处理和命令处理结果回复等,在定时循环中,完成过期key的检测等。

redis 在 blpop 命令处理过程时,首先会去查找 key 对应的 list ,如果存在,则 pop 出数据响应给客户端。否则将对应的 key 写入到 blocking_keys 数据结构当中,对应的 value 是被阻塞的 client。
当下次 push 命令发出时,服务器检查 blocking_keys 当中是否存在对应的 key,如果存在,则将 key 添加到 ready_keys 链表当中, 同时将 push 进来的数据插入到 key 对应的 list 中并响应客户端。

服务端在每次的 EventLoop 当中处理完客户端 IO 请求之后,接着会遍历 ready_keys 链表获取 key ,并从 blocking_keys 链表当中找到对应的 client,依次将 key 对应 list 的数据 pop 出来并响应给对应的 client,可以看到整个过程并不会阻塞EventLoop本身。

Set

Set 是 String 类型的无序集合,集合成员是唯一的,也就是说不能出现重复的元素,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择。

SADD key member1 [member2] : 向集合添加一个或多个成员。

SDIFF key1 [key2] : 返回给定所有集合的差集。

SINTER key1 [key2] : 返回给定所有集合的交集。

SUNION key1 [key2] : 返回所有给定集合的并集。

SDIFFSTORE destination key1 [key2] : 返回给定所有集合的差集并存储在集合 destination 中。

SINTERSTORE destination key1 [key2] : 返回给定所有集合的交集并存储在集合 destination 中。

SUNIONSTORE destination key1 [key2] : 所有给定集合的并集存储在集合 destination 中。

SMOVE source destination member : 将 member 元素从 source 集合移动到集合 destination 中。

SISMEMBER key member : 判断 member 元素是否是集合 key 的成员。

SCARD key : 获取集合中元素的数量。

SMEMBERS key : 返回集合中的所有成员。

SPOP key : 移除并返回集合中的一个随机元素。

SREM key member1 [member2] : 移除集合中一个或多个成员。

SRANDMEMBER key [count] : 从结合中返回 count 个随机成员。

如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。
如果 count 大于等于集合基数,那么返回整个集合。
如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。

SSCAN key cursor [MATCH pattern] [COUNT count] : 迭代集合中的元素,类似scan命令。

Zset

当你需要一个有序的并且不重复的集合列表,那么可以选择 Zset 数据结构, Zset 每个元素都会关联一个double类型的分数,通过分数来为里面的成员进行从小到大的排序。

注意: 有序集合的成员是唯一的,但分数(score)却可以重复。

ZADD key score1 member1 [score2 member2] : 向有序集合添加一个或多个成员,或者更新已存在成员的分数。

ZCARD key : 获取有序集合中的元素数量。

ZCOUNT key min max :统计有序集合中指定分数区间的成员数量(含min和max)。

ZINCRBY key increment member : 有序集合中对指定成员的分数加上增量 increment。

ZINTERSTORE destination numkeys key [key ...] : 计算 numkeys 个 key 的交集并将结果集存储在新的有序集合 destination 中。

ZUNIONSTORE destination numkeys key [key ...] : 计算 numkeys 个 key 的并集并将结果集存储在新的有序集合 destination 中。

ZLEXCOUNT key min max : 统计有序集合指定字典区间内的成员数量,成员是能够用范围标识的那种数据,例如数字(0-n)和字母(a-z)。

ZRANGEBYLEX key min max [LIMIT offset count] : 获取有序集合指定字典区间内的成员。

ZREM key member [member ...] : 移除有序集合中的一个或多个成员。

ZREMRANGEBYLEX key min max : 移除有序集合中指定字典区间的所有成员

ZREMRANGEBYRANK key start stop : 移除有序集合中给定的索引区间的所有成员。

ZREMRANGEBYSCORE key min max : 移除有序集合中指定分数区间的所有成员。

ZRANGE key start stop [WITHSCORES] : 返回指定索引区间内的成员,成员按分数值递增来排序。

ZREVRANGE key start stop [WITHSCORES] : 返回指定索引区间内的成员,成员按分数值递减来排序。

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] : 获取按分数递增排序后的指定分数区间的成员。

ZREVRANGEBYSCORE key max min [WITHSCORES] : 获取按分数递减排序后的指定分数区间的成员。

ZSCORE key member : 返回有序集中,成员的分数值。

ZRANK key member : 获取有序集合中成员按分数递增排序后的索引。

ZREVRANK key member : 获取有序集合中成员按分数递减排序后的索引。

HyperLogLog

HyperLogLog 是一种非常省内存的用来做数据统计的算法,HyperLogLog 的优点是在输入元素的数量或者体积非常大时,计算基数所需的空间总是固定的、并且是很小的,每个 HyperLogLog 键占用的内存是 12 KB 内存,理论上可以存储 2^64 值。

另外需要注意的是,HyperLogLog 只计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

假设每天 IP 有 100 万个 :

一个IP消耗15字节,如果用 set 存储,那么 100 万个 IP 就是 15M,如果 1 千万, 就是 150M。

而 HyperLogLog 每个 key 能存储的值是 2^64 个,其所占的内存仅仅是 12k,如果把这 1000 万 IP 存到 HyperLogLog 中连 12k 都不到。

这和计算基数时, 元素越多耗费内存就越多的集合形成鲜明对比,当然存到 HyperLogLog 的前提是,你并不关心每条 IP 到底是什么。

HyperLogLog 适合用于如下业务场景:

  • 统计注册 IP 数
  • 统计每日访问 IP 数
  • 统计页面实时 UV 数
  • 统计在线用户数
  • 统计用户每天搜索不同词条的个数

下面是 HyperLogLog 提供的命令

PFADD key element [element ...] : 添加指定元素到 HyperLogLog 中。

PFCOUNT key [key ...] : 返回给定 HyperLogLog 的基数估算值。

只能比较准确的估算出基数,而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误。

PFMERGE destkey sourcekey [sourcekey ...] : 将多个 HyperLogLog 合并为一个 HyperLogLog。

如果我们存了每天的 ip,那么利用这个命令就可以 可以计算每月 IP 总数。

php-redis 参考

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注