Redis
什么是Redis?
定义:REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 通常被称为数据结构服务器
特性:
Redis 是开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、
可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库
提供多种语言的 API
Redis三个特点:
·支持持久化,即将内存中的数据保存在磁盘上,重启时可再次加载使用
·除了支持简单的数据类型外,添加了zset、hash等其他数据结构
·支持master-slave模式的数据备份
Redis优势:
·读写性能搞,具备丰富的数据类型
·具备原子性,通过MULTI、EXEC指令包起来
·丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
数据类型:
·字符串 String,基本数据类型,可以包含任何数据,最大存储512MB
存储:set key value
获取:get key
删除:del key
·哈希 hash,适合存储对象,string类型的field=》value,每个hash可以存储223-1键值对
存储:hmset key filed1 value1 filed2 value2
获取:hget key fieldname
删除:del key
·列表 list,简单的字符串列表,列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。
插入: lplush key value
获取: lrange key
删除:del
·集合 sets,字符串无序集合,元素值唯一,通过hash表实现,添加、删除、查找O(1)
添加: sadd key value
获取:smembers key
删除:del key
·有序集合 sorted sets(zset)元素值唯一但是 有序,通过double类型的‘分数’来进行从小到大排序的,不同的value的分数可重复
添加:zadd key score member
获取:ZRANGEBYSCORE runoob 0 1000
删除:del key
Redis安装
下载地址:https://github.com/tporadowski/redis/releases
1、下载zip压缩文件
2、解压本地
3、启动redis
redis-server.exe redis.windows.conf
4、使用Redis
redis-cli.exe -h 127.0.0.1 -p 6379
Redis配置
1、找到Redis配置文件:端口、主机、超时、日志等
2、配置语法:
CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
字段名 新值
CONFIG SET loglevel "notice"
Redis命令
语法:redis -cli连接客户端
CMD配置环境变量后可使用
redis-server.exe 启动服务
redis-cli.exe -h 127.0.0.1 -p 6379 连接服务,启动客户端
远程
redis -cli -h host -p port -a密码
key命令
del、dump序列化,exists ,move key db(目标数据库)
String 命令:
返回子串:getrange key start end
Hash命令:Hdel key field……删除一个或多个字段
Hkeys 获取表中所有指定的key字段,
hgetAll key 获取所有指定key的值和字段,hset key 字段 value 修改字段值
list命令:
序号 命令及描述
1 BLPOP key1 [key2 ] timeout
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
2 BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
3 BRPOPLPUSH source destination timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
4 LINDEX key index
通过索引获取列表中的元素
5 LINSERT key BEFORE|AFTER pivot value
在列表的元素前或者后插入元素
6 LLEN key
获取列表长度
7 LPOP key
移出并获取列表的第一个元素
8 LPUSH key value1 [value2]
将一个或多个值插入到列表头部
9 LPUSHX key value
将一个值插入到已存在的列表头部
10 LRANGE key start stop
获取列表指定范围内的元素
11 LREM key count value
移除列表元素
12 LSET key index value
通过索引设置列表元素的值
13 LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
14 RPOP key
移除列表的最后一个元素,返回值为移除的元素。
15 RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回
16 RPUSH key value1 [value2]
在列表中添加一个或多个值
17 RPUSHX key value
为已存在的列表添加值
zset命令
序号 | 命令及描述 |
---|---|
1 | [ZADD key score1 member1 score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
2 | ZCARD key 获取有序集合的成员数 |
3 | ZCOUNT key min max 计算在有序集合中指定区间分数的成员数 |
4 | ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment |
5 | [ZINTERSTORE destination numkeys key key …] 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中 |
6 | ZLEXCOUNT key min max 在有序集合中计算指定字典区间内成员数量 |
7 | [ZRANGE key start stop WITHSCORES] 通过索引区间返回有序集合指定区间内的成员 |
8 | [ZRANGEBYLEX key min max LIMIT offset count] 通过字典区间返回有序集合的成员 |
HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
劣势:只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素
1 | [PFADD key element element …] 添加指定元素到 HyperLogLog 中。 |
---|---|
2 | [PFCOUNT key key …] 返回给定 HyperLogLog 的基数估算值。 |
3 | [PFMERGE destkey sourcekey sourcekey …] 将多个 HyperLogLog 合并为一个 HyperLogLog |
发布订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
序号 | 命令及描述 |
---|---|
1 | [PSUBSCRIBE pattern pattern …] 订阅一个或多个符合给定模式的频道。 |
2 | [PUBSUB subcommand argument [argument …]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel message 将信息发送到指定的频道。 |
4 | [PUNSUBSCRIBE pattern [pattern …]] 退订所有给定模式的频道。 |
5 | [SUBSCRIBE channel channel …] 订阅给定的一个或多个频道的信息。 |
6 | [UNSUBSCRIBE channel [channel …]] 指退订给定的频道。 |
事务
redis一次可执行多个事务
三个保证
1、批量操作在发送exec命令前放入队列缓存
2、收到命令后进入事务执行,任意事务失败不会影响其他事务执行
3、执行过程中,其他命令不会被插入到当前事务序列
开始事务=》命令入队=》执行事务
注意:事务执行不具备原子性
序号 | 命令及描述 |
---|---|
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。 |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | [WATCH key key …] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
脚本
Redis 脚本使用 Lua 解释器来执行脚本,执行命令:eval
语法:EVAL script numkeys key [key …] arg [arg …]
redis 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"
1 | [EVAL script numkeys key key …] arg [arg …] 执行 Lua 脚本。 |
---|---|
2 | [EVALSHA sha1 numkeys key key …] arg [arg …] 执行 Lua 脚本。 |
3 | [SCRIPT EXISTS script script …] 查看指定的脚本是否已经被保存在缓存当中。 |
4 | SCRIPT FLUSH 从脚本缓存中移除所有脚本。 |
5 | SCRIPT KILL 杀死当前正在运行的 Lua 脚本。 |
6 | SCRIPT LOAD script 将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。 |
连接
Redis 连接命令主要是用于连接 redis 服务
序号 | 命令及描述 |
---|---|
1 | AUTH password 验证密码是否正确 |
2 | ECHO message 打印字符串 |
3 | PING 查看服务是否运行 |
4 | QUIT 关闭当前连接 |
5 | SELECT index 切换到指定的数据库 |
服务器
管理redis服务
序号 | 命令及描述 |
---|---|
1 | BGREWRITEAOF 异步执行一个 AOF(AppendOnly File) 文件重写操作 |
2 | BGSAVE 在后台异步保存当前数据库的数据到磁盘 |
3 | [CLIENT KILL ip:port] [ID client-id] 关闭客户端连接 |
4 | CLIENT LIST 获取连接到服务器的客户端连接列表 |
5 | CLIENT GETNAME 获取连接的名称 |
6 | CLIENT PAUSE timeout 在指定时间内终止运行来自客户端的命令 |
7 | CLIENT SETNAME connection-name 设置当前连接的名称 |
8 | CLUSTER SLOTS 获取集群节点的映射数组 |
9 | COMMAND 获取 Redis 命令详情数组 |
10 | COMMAND COUNT 获取 Redis 命令总数 |
11 | COMMAND GETKEYS 获取给定命令的所有键 |
12 | TIME 返回当前服务器时间 |
13 | [COMMAND INFO command-name command-name …] 获取指定 Redis 命令描述的数组 |
14 | CONFIG GET parameter 获取指定配置参数的值 |
15 | CONFIG REWRITE 对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写 |
16 | CONFIG SET parameter value 修改 redis 配置参数,无需重启 |
17 | CONFIG RESETSTAT 重置 INFO 命令中的某些统计数据 |
18 | DBSIZE 返回当前数据库的 key 的数量 |
19 | DEBUG OBJECT key 获取 key 的调试信息 |
20 | DEBUG SEGFAULT 让 Redis 服务崩溃 |
21 | FLUSHALL 删除所有数据库的所有key |
22 | FLUSHDB 删除当前数据库的所有key |
23 | [INFO section] 获取 Redis 服务器的各种信息和统计数值 |
24 | LASTSAVE 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 |
25 | MONITOR 实时打印出 Redis 服务器接收到的命令,调试用 |
26 | ROLE 返回主从实例所属的角色 |
27 | SAVE 同步保存数据到硬盘 |
28 | [SHUTDOWN NOSAVE] [SAVE] 异步保存数据到硬盘,并关闭服务器 |
29 | SLAVEOF host port 将当前服务器转变为指定服务器的从属服务器(slave server) |
30 | [SLOWLOG subcommand argument] 管理 redis 的慢日志 |
31 | SYNC 用于复制功能(replication)的内部命令 |
GEO
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。
Redis GEO 操作方法有:
-
geoadd:添加地理位置的坐标;一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。
GEOADD key longitude latitude member [longitude latitude member …]
-
geopos:获取地理位置的坐标。GEOPOS key member [member …]
-
geodist:计算两个位置之间的距离。GEODIST key member1 member2 [m|km|ft|mi]
-
georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
-
georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
-
geohash:返回一个或多个位置对象的 geohash 值。GEOHASH key member [member …]
stream
Redis Stream 主要用于消息队列(MQ,Message Queue)
发布订阅 (pub/sub) 可实现消息队列的功能,
缺点:消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
Stream 提供了消息的持久化和主备复制功能、客户端可以访问任意时刻数据、可记录客户端的**访问位置****、保证消息不丢失
Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:
每个 Stream 都有唯一的名称,它就是 Redis 的 key,首次使用 xadd 指令追加消息时自动创建。
- Consumer Group :消费组,使用 XGROUP CREATE 命令创建,一个消费组有多个消费者(Consumer)。
- last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
- pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)。
消息队列相关命令:
-
XADD - 添加消息到末尾;XADD key ID field value [field value …]
- key :队列名称,如果不存在就创建
- ID :消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性。
- field value : 记录。
-
XTRIM - 对流进行修剪,限制长度XTRIM key MAXLEN [~] count
- key :队列名称
- MAXLEN :长度
- count :数量
-
XDEL - 删除消息;key id
-
XLEN - 获取流包含的元素数量,即消息长度 key
-
XRANGE - 获取消息列表,会自动过滤已经删除的消息;XRANGE key start end [COUNT count]
- key :队列名
- start :开始值, - 表示最小值
- end :结束值, + 表示最大值
- count :数量
-
XREVRANGE - 反向获取消息列表,ID 从大到小
-
XREAD - 以阻塞或非阻塞方式获取消息列表
-
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
- count :数量
- milliseconds :可选,阻塞毫秒数,没有设置就是非阻塞模式
- key :队列名
- id :消息 ID
-
消费者组相关命令:
-
XGROUP CREATE - 创建消费者组
XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
- key :队列名称,如果不存在就创建
- groupname :组名。
- $ : 表示从尾部开始消费,只接受新消息,当前 Stream 消息会全部忽略。
从头开始消费:
XGROUP CREATE mystream consumer-group-name 0-0
从尾部开始消费:
XGROUP CREATE mystream consumer-group-name $
-
XREADGROUP GROUP - 读取消费者组中的消息
使用 XREADGROUP GROUP 读取消费组中的消息,语法格式:
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
- group :消费组名
- consumer :消费者名。
- count : 读取数量。
- milliseconds : 阻塞毫秒数。
- key : 队列名。
- ID : 消息 ID。
XREADGROUP GROUP consumer-group-name consumer-name COUNT 1 STREAMS mystream >
-
XACK - 将消息标记为"已处理"
-
XGROUP SETID - 为消费者组设置新的最后递送消息ID
-
XGROUP DELCONSUMER - 删除消费者
-
XGROUP DESTROY - 删除消费者组
-
XPENDING - 显示待处理消息的相关信息
-
XCLAIM - 转移消息的归属权
-
XINFO - 查看流和消费者组的相关信息;
-
XINFO GROUPS - 打印消费者组的信息;
-
XINFO STREAM - 打印流信息
高级
数据备份与恢复
save命令:备份数据,在安装目录中创建dump.rdb文件
bgsave:后台执行的数据备份命令
恢复数据:
CONFIG GET dir 输出安装路径
安全
设置访问密码:
CONFIG set requirepass 设置密码
CONFIG get requirepass 查看是否设置密码
auth 密码获取客户端访问权限
性能测试
Redis 性能测试是通过同时执行多个命令实现的
语法:redis-benchmark [option] [option value]
该命令是在 redis 的目录下执行的,而不是 redis 客户端的内部指令
redis 性能测试工具可选参数如下所示:
序号 | 选项 | 描述 | 默认值 |
---|---|---|---|
1 | -h | 指定服务器主机名 | 127.0.0.1 |
2 | -p | 指定服务器端口 | 6379 |
3 | -s | 指定服务器 socket | |
4 | -c | 指定并发连接数 | 50 |
5 | -n | 指定请求数 | 10000 |
6 | -d | 以字节的形式指定 SET/GET 值的数据大小 | 2 |
7 | -k | 1=keep alive 0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | |
9 | -P | 通过管道传输 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | –csv | 以 CSV 格式输出 | |
12 | *-l*(L 的小写字母) | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表。 | |
14 | *-I*(i 的大写字母) | Idle 模式。仅打开 N 个 idle 连接并等待。 |
实例
$ 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
实例中主机为 127.0.0.1,端口号为 6379,执行的命令为 set,lpush,请求数为 10000,通过 -q 参数让结果只显示每秒执行的请求数。
客户端连接
通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:
- 客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。
- 为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
- 创建一个可读的文件事件,监听该客户端 socket 的数据发送
最大连接数:2.4,被直接硬编码在代码里面的,2.6可修改
config get maxclients:查看当前最大连接数
redis-server --maxclients 100000 启动时设置最大连接数
S.N. | 命令 | 描述 |
---|---|---|
1 | CLIENT LIST | 返回连接到 redis 服务的客户端列表 |
2 | CLIENT SETNAME | 设置当前连接的名称 |
3 | CLIENT GETNAME | 获取通过 CLIENT SETNAME 命令设置的服务名称 |
4 | CLIENT PAUSE | 挂起客户端连接,指定挂起的时间以毫秒计 |
5 | CLIENT KILL | 关闭客户端连接 |
管道技术
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。
步骤:
- 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
- 服务端处理命令,并将结果返回给客户端。
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
优势:提升Redis服务性能
分区
·将数据分割到多个redis处理
·每个实例只保存key的一个子集
优势
·利用多台计算机内存的和值,创建大型数据库
·通过多核、网络适配器以及多台计算机,可扩展计算能力、网络带宽;
不足:
·不支持多个key操作
·多个key的redis事务不能使用
·数据处理较复杂
·增加、删除容量比较复杂;redis集群大多数支持在运行时增加、删除节点的透明数据平衡的能力,但是类似于客户端分区、代理等其他系统则不支持这项特性。然而,一种叫做presharding的技术对此是有帮助的。
分区类型
Redis 有两种类型分区。 假设有4个Redis实例 R0,R1,R2,R3,和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个Redis服务。
范围分区
最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。
比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。
哈希分区
另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:
-
用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。
-
对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。
注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。
1,R2,R3,和类似user:1,user:2这样的表示用户的多个key,对既定的key有多种不同方式来选择这个key存放在哪个实例中。也就是说,有不同的系统来映射某个key到某个Redis服务。
范围分区
最简单的分区方式是按范围分区,就是映射一定范围的对象到特定的Redis实例。
比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
不足就是要有一个区间范围到实例的映射表。这个表要被管理,同时还需要各 种对象的映射表,通常对Redis来说并非是好的方法。
哈希分区
另外一种分区方法是hash分区。这对任何key都适用,也无需是object_name:这种形式,像下面描述的一样简单:
-
用一个hash函数将key转换为一个数字,比如使用crc32 hash函数。对key foobar执行crc32(foobar)会输出类似93024922的整数。
-
对这个整数取模,将其转化为0-3之间的数字,就可以将这个整数映射到4个Redis实例中的一个了。93024922 % 4 = 2,就是说key foobar应该被存到R2实例中。
注意:取模操作是取除的余数,通常在多种编程语言中用%操作符实现。