Redis核心数据类型解析——string篇
Redis的常见数据类型
预备
- Redis的命令有上百个,只是死记硬背比较困难,但是如何理解Redis的一些机制,会发现这些命令有很强的通用性。
- Redis不是万金油,有些数据结构和命令必须在特定的场景下使用,一旦使用不当可能会对Redis自身造成致命伤害
全局命令
Redis有5种数据结构,但是它们都是对值而言,不过对于键,倒是有一些通用的命令。
KEYS
返回所有满足样式的key。支持如下
• h?llo 匹配 hello , hallo 和 hxllo
• h*llo 匹配 hllo 和 heeeello
• h[ae]llo 匹配 hello 和 hallo 但不匹配 hillo
• hello 匹配 hallo , hbllo , ... 但不匹配 hello
• h[a-b]llo 匹配 hallo和 hbllo
举例如下
EXISTS
判断某个key是否存在
举个例子
DEL
删除指定的key
举个例子

TTL
获取指定key的剩余时间
TYPE
返回key对应的数据类型

数据结构和内部编码
Redis的数据结构和内部编码
数据结构 | 内部编码 |
string | raw |
int | |
embstr | |
hash | hashtable |
ziplist | |
list | linkedlist |
ziplist | |
set | hashtable |
intset | |
zset | skiplist |
ziplist |

Redis这样设计有很大的好处:
1) 可以改进内部编码,⽽对外的数据结构和命令没有任何影响,这样⼀旦开发出更优秀的内部编码, ⽆需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了⼀种更为优秀的内部编码实现,⽽对⽤⼾来说基本⽆感知
2)多种内部编码实现可以在不同场景下发挥各⾃的优势,例如 ziplist ⽐较节省内存,但是在列表元素 ⽐较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为 linkedlist,整个过程⽤⼾同样⽆感知。
单线程架构
简介

微观上客户端发送命令的时间是有先后次序的
为什么单线程可以这么快
- 纯内存访问。Redis将所有的数据放在内存中,内存的响应时长大约是100ns,这是Redis达到每秒万级别的重要基础。
- 非阻塞IO。Redis使用epoll作为IO多路复用技术的实现,在加上Redis自身的事件处理模型将epoll中的链接、读写、关闭都转换成事件,不在网络IO上浪费过多的事件。
- 单线程避免了线程切换和竞态产生的消耗。单线程可以简化数据结构和算法的视线,让程序模型更加简单;其次避免了多线程中在线程竞争同一份共享资源时带来的切换的等待消耗。
String字符串
- Redis中的所有的键的类型都是字符串类型,而且其他几种数据类型也都是在字符串类似基础上构建的。
- 字符串的值实际可以是字符串,包含一般格式的字符串或者类似JSON、XML格式的字符串,数字。可以使整型或者浮点型;甚至是二进制流数据
常见命令
set
将string类型的value设置到key中。如果key之前存在,就修改;不存在就创建。
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
SET命令支持多种选项来影响它的行为
- EX seconds —— 使用秒为单位来设置key的过期时间
- PX milliseconds——使用毫秒作为单位设置key的过期时间
- NX——只有key不存在的时候才设置
- XX——只有key存在的时候才设置
举个例子
get
GET key
MGET key [key ...]
举个例子
mset
一次性设置多个key的值
MSET key value [key value ...]
举个例子
setnx
SETNX key value
计数命令
incr

incrby
INCRBY key decrement
举个例子
DECR key
DECRBY key decrement
INCRBYFLOAT key increment
其他命令
append
APPEND KEY VALUE
getrange
GETRANGE key start end
SETRANGE key offset value
STRLEN key
结算
内部编码
- int:8个字节的整型
- embstr:小于等于39个字节的字符串
- raw:大于39个字节的字符串