Redis:
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs and geospatial indexes with radius queries. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.
Redis 安装
Mac
$ brew install redis
$ brew services start redis
Linux
# ubuntu
$ sudo apt-get install redis-server
$ redis-server
# centos
$ sudo yum install epel-release
$ sudo yum install redis -y
$ sudo systemctl start redis.service && systemctl enable redis.service
Redis 的特点
- 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速
- 数据结构简单,对数据操作也简单
- 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗
- Redis 是线程安全的(因为只有一个线程),其所有操作都是原子的,不会因并发产生数据异常
- 使用 I/O 多路复用模型
- 使用高耗时的 Redis 命令是很危险的,会占用唯一的一个线程的大量处理时间,导致所有的请求都被拖慢
Redis 的数据类型
Redis 采用 Key-Value
型的基本数据结构,任何二进制序列都可以作为 Redis 的 Key
使用。Redis 的 key
是 二进制安全 的,这意味着你可以用任意二进制序列作为 key
值,包括空字符串。
key
需要注意的事项:
- 使用太长的
key
值并不是 a good idea。太长的key
值不仅消耗内存,而且在数据集中查找的成本也很高 - 太短的
key
值也不是 a good idea,缺失可读性 - 最好使用统一的规范来设计
key
,比如object-type:id
- Redis 允许的最大 key size 是
512 MB
( String 和 Bitmaps 的长度限制也是512 MB
)
1. Binary-safe strings
# 为一个 key 赋值
> set mykey somevalue
OK
-------- mykey --------
| somevalue |
-----------------------
图示
# 获取某个 key 对应的值
> get mykey
"somevalue"
# 如果 key 值存在,直接执行 set 操作会替换掉对应的 value 值
# 只对不存在的 key 赋值
> set mykey newval nx
(nil)
# 只对已存在的 key 赋值
> set mykey newval xx
OK
# 将 value 值作为整型或浮点型数字使用
> set counter 100
# 自增 1
> incr counter
101
# 自减 1
> decr counter
100
# 按指定的整型数值自增
> incrby counter 50
150
# 按指定的整型数值自减
> decrby counter 50
100
# 为多个 key 赋值
> mset a 10 b 20 c 30
OK
# 获取多个 key 对应的值
> mget a b c
1) "10"
2) "20"
3) "30"
# 查询和修改 key
# exists: key 是否存在
# del: 删除 key
# type: key 的类型
> set mykey hello
OK
> exists mykey
1
> type mykey
string
> del mykey
1
> exists mykey
0
> type mykey
none
# 过期时间
> set key some-value
# 设置过期时间,默认单位为秒
> expire key 5
1
# 或者上面的过程可以一步完成
> set key some-value ex 5
OK
# 查看剩余生存时间
> ttl key
4
2. Lists
# 添加一个元素到列表的头部(左边)或者尾部(右边)。
# 列表的尾部
> rpush mylist A
1
> rpush mylist B
2
# 列表的头部
> lpush mylist first
3
-------- mylist--------
| first |
| A |
| B |
-----------------------
图示
# 提取列表中的元素
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
# 添加多个元素
> rpush mylist C D E
# 移除元素
> rpop mylist
# 修剪列表
# ltrim 保留指定范围的指定元素
> rpush mylist 1 2 3 4 5
5
> ltrim mylist 0 2
OK
> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
# list 的阻塞操作
# 对于用 list 实现一个 producer / consumer 的问题,可以用 lpush / rpop 或者 rpush / lpop
# 实现,但是会对 Redis 增加过多无用的请求和延迟,不是好的解决方案。
# brpop / blpop 实现阻塞操作
# 例如:等待队列添加新的元素,如果 5 秒内没有新的元素返回 null
> brpop tasks 5
## 数组长度
> llen mylist
3. Hashes
# 赋值
> hset hash_key1 sub_key1 value1
1
---------- hash_key1 ----------
| sub_key1 value1 |
| sub_key2 value2 |
| sub_key3 value3 |
-------------------------------
图示
# 获取值
> hget hash_key1 sub_key1
"value1"
# 操作多个值
> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hmget user:1000 username birthyear
1) "antirez"
2) "1977"
# 获取散列包含的所有键值对
> hgetall user:1000
1) "username"
2) "antirez"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"
# 获取不存在的键值
> hmget user:1000 no-such-field
(nil)
# 对 hash 中的值进行自增操作
> hincrby user:1000 birthyear 10
1987
4. Sets
# 添加元素
> sadd myset 1 2 3
-------- myset --------
| 1 |
| 2 |
| 3 |
-----------------------
图示
# 移除元素
> srem myset 1
# 查看集合成员
> smembers myset
1. 3
2. 2
# 元素是否在集合中
> sismember myset 3
# 集合包含的元素的数量
> scard myset
# 随机移除集合元素
> spop myset
# 交集
> sinter myset1 myset2
# 将交集存储在 dest-key 中
> sinter dest-key myset1 myset2
# 差集
> sdiff myset1 myset2
# 将差集存储在 dest-key 中
> sdiff dest-key myset1 myset2
# 并集
> sunion myset1 myset2
# 将并集存储在 dest-key 中
> sunion dest-key myset1 myset2
5. Sorted sets
# 添加成员
> zadd key-name score member
---------- key-name ----------
| member1 score1 |
| member2 score2 |
| member3 score3 |
------------------------------
图示
# 移除成员
> zrem key-name member
# 成员数量
> zcard key-name
# 将 member 的分值加上 increment
> zincrby key-name increment member
# 分值介于 min 和 max 之间的成员数量
> zcount key-name min max
# 成员在有序集合中的排名
> zrank key-name member
# 成员的分值
> zscore key-name member
# 有序集合中排名介于 start 和 stop 之间的成员
> zrange key-name start stop
# 有序集合中排名介于 start 和 stop 之间的成员,从大到小排序
> zrevrange key-name start stop
# 返回指定成员区间内的成员,按成员字典正序排序,
# min 和 max 可以用 [值 或者 - 表示最小值 + 表示最大值
> zrangebylex key-name min max
Redis 5.0 添加的新功能:
# 移除有序集合中分值最大的 count 个元素
> ZPOPMAX key [count]
# 移除有序集合中分值最小的 count 个元素
> ZPOPMIN key [count]
# 上述连个命令的阻塞变种,用 timeout 指定命令的最长阻塞时间:
> BZPOPMAX key [key ...] timeout
> BZPOPMIN key [key ...] timeout
6. Bitmaps
# 面向字节操作,最大长度为 512 M,即最多 2^32 个字节
# 设置指定偏移量上的位,
> setbit key offset value
# 获取指定偏移量上的位
> getbit key offset
# 统计设置为 1 的位的数量,单位为字节,即 8 个位置
> bitcount key [start] [stop]
# 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上
> bitop [AND / OR / XOR / NOT] destkey key [key ...]
# 寻找指定值的位置
> bitpos key value
7. HyperLogLogs
# 一种被用于计算唯一事物的概率数据结构
# 添加元素
> pfadd key value [value ...]
# 唯一元素的近似数量
> pfcount key
# 合并多个 HLL,并存储在 destkey 中
> pfmerge destkey key [key ...]