@dungan
2020-03-28T03:30:53.000000Z
字数 9386
阅读 101
Redis
linux 上的安装
$ wget http://download.redis.io/releases/redis-5.0.2.tar.gz
$ tar xzf redis-5.0.2.tar.gz -C /usr/local/
$ cd /usr/local/redis-5.0.2
$ make
编译的二进制文件位于 src 目录
$ cd src
$ redis-server
测试
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
这样 redis 就安装成功了。
redis 的配置文件位于文件redis安装目录下的 redis.conf 中,下面两个命令可以操作配置项
# CONFIG GET config_key:读取配置项
CONFIG GET *
# CONFIG SET config_key config_value : 设置配置项
CONFIG SET loglevel "notice"
还可以直接通过命令行传递Redis配置参数
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:指定包含其它的配置文件,常用在多实例场景中载入一些个性化配置。
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服务的连接。
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特别适合用于存储对象。
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 命令。
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 是 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 每个元素都会关联一个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 键占用的内存是 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 总数。