Redis数据类型
-
String(字符串)
string是redis最基本的类型,且二进制安全可包含任何数据。
[root@WaWen /start_redis]#ls redis-cli.sh redis-conf.sh redis-server.sh [root@WaWen /start_redis]#./redis-cli.sh # string的set、get 127.0.0.1:6379> set name "wawen" OK 127.0.0.1:6379> get name "wawen" #-------------------------------------------------- # 命令及描述 # 设置指定 key 的值 SET key value # 获取指定 key 的值。 GET key # 返回 key 中字符串值的子字符 GETRANGE key start end # 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 GETSET key value # 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 GETBIT key offset # 获取所有(一个或多个)给定 key 的值。 MGET key1 [key2..] # 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 SETBIT key offset value # 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 SETEX key seconds value # 只有在 key 不存在时设置 key 的值。 SETNX key value # 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。 SETRANGE key offset value # 返回 key 所储存的字符串值的长度。 STRLEN key # 同时设置一个或多个 key-value 对。 MSET key value [key value ...] # 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 MSETNX key value [key value ...] # 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 PSETEX key milliseconds value # 将 key 中储存的数字值增一。 INCR key # 将 key 所储存的值加上给定的增量值(increment) 。 INCRBY key increment # 将 key 所储存的值加上给定的浮点增量值(increment) 。 INCRBYFLOAT key increment # 将 key 中储存的数字值减一。 DECR key # key 所储存的值减去给定的减量值(decrement) 。 DECRBY key decrement # 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。 APPEND key value
-
hash(哈希)
hash是一个键值对集合
# 插入数据 127.0.0.1:6379> hmset hash_1 f1 "v1" f2 "v2" f3 "v3" OK # 获取数据 127.0.0.1:6379> hmget hash_1 f1 f2 f3 1) "v1" 2) "v2" 3) "v3" #-------------------------------------------------- # 命令及描述 # 删除一个或多个哈希表字段 HDEL key field1 [field2] # 查看哈希表 key 中,指定的字段是否存在。 HEXISTS key field # 获取存储在哈希表中指定字段的值。 HGET key field # 获取在哈希表中指定 key 的所有字段和值 HGETALL key # 为哈希表 key 中的指定字段的整数值加上增量 increment 。 HINCRBY key field increment # 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 HINCRBYFLOAT key field increment # 获取所有哈希表中的字段 HKEYS key # 获取哈希表中字段的数量 HLEN key # 获取所有给定字段的值 HMGET key field1 [field2] # 同时将多个 field-value (域-值)对设置到哈希表 key 中。 HMSET key field1 value1 [field2 value2 ] # 将哈希表 key 中的字段 field 的值设为 value 。 HSET key field value # 只有在字段 field 不存在时,设置哈希表字段的值。 HSETNX key field value # 获取哈希表中所有值。 HVALS key # 迭代哈希表中的键值对。 HSCAN key cursor [MATCH pattern] [COUNT count]
-
list(列表)
redis是一个简单的字符串列表,按照插入顺序排序。也可插入头部或尾部
# 顺序添加 127.0.0.1:6379> lpush list_1 redis (integer) 1 127.0.0.1:6379> lpush list_1 docker (integer) 2 127.0.0.1:6379> lpush list_1 shell (integer) 3 127.0.0.1:6379> lpush list_1 vim (integer) 4 # 遍历结果 127.0.0.1:6379> lrange list_1 0 10 1) "vim" 2) "shell" 3) "docker" 4) "redis" #-------------------------------------------------- # 命令及描述 # 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 BLPOP key1 [key2 ] timeout # 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 BRPOP key1 [key2 ] timeout # 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 BRPOPLPUSH source destination timeout # 通过索引获取列表中的元素 LINDEX key index # 在列表的元素前或者后插入元素 LINSERT key BEFORE|AFTER pivot value # 获取列表长度 LLEN key # 移出并获取列表的第一个元素 LPOP key # 将一个或多个值插入到列表头部 LPUSH key value1 [value2] # 将一个值插入到已存在的列表头部 LPUSHX key value # 获取列表指定范围内的元素 LRANGE key start stop # 移除列表元素 LREM key count value # 通过索引设置列表元素的值 LSET key index value # 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 LTRIM key start stop # 移除列表的最后一个元素,返回值为移除的元素。 RPOP key # 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 RPOPLPUSH source destination # 在列表中添加一个或多个值 RPUSH key value1 [value2] # 为已存在的列表添加值 RPUSHX key value
-
set(集合)
Redis 的 Set 是 string 类型的无序集合,且数据唯一。
# 插入数据 127.0.0.1:6379> sadd sadd_1 docker (integer) 1 127.0.0.1:6379> sadd sadd_1 shell (integer) 1 127.0.0.1:6379> sadd sadd_1 vim (integer) 1 127.0.0.1:6379> sadd sadd_1 shell (integer) 0 # 遍历结果 127.0.0.1:6379> smembers sadd_1 1) "vim" 2) "shell" 3) "docker" #-------------------------------------------------- # 命令及描述 # 向集合添加一个或多个成员 SADD key member1 [member2] # 获取集合的成员数 SCARD key # 返回第一个集合与其他集合之间的差异。 SDIFF key1 [key2] # 返回给定所有集合的差集并存储在 destination 中 SDIFFSTORE destination key1 [key2] # 返回给定所有集合的交集 SINTER key1 [key2] # 返回给定所有集合的交集并存储在 destination 中 SINTERSTORE destination key1 [key2] # 判断 member 元素是否是集合 key 的成员 SISMEMBER key member # 返回集合中的所有成员 SMEMBERS key # 将 member 元素从 source 集合移动到 destination 集合 SMOVE source destination member # 移除并返回集合中的一个随机元素 SPOP key # 返回集合中一个或多个随机数 SRANDMEMBER key [count] # 移除集合中一个或多个成员 SREM key member1 [member2] # 返回所有给定集合的并集 SUNION key1 [key2] # 所有给定集合的并集存储在 destination 集合中 SUNIONSTORE destination key1 [key2] # 迭代集合中的元素 SSCAN key cursor [MATCH pattern] [COUNT count]
-
zset(有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
# 插入操作 zadd key score member # 插入数据 127.0.0.1:6379> zadd zadd_1 0 shell 0 dubbo 0 docker (integer) 3 127.0.0.1:6379> zadd zadd_1 1 vim (integer) 1 127.0.0.1:6379> zadd zadd_1 2 git (integer) 1 127.0.0.1:6379> zadd zadd_1 3 redis (integer) 1 # 遍历结果 127.0.0.1:6379> zrange zadd_1 0 10 1) "docker" 2) "dubbo" 3) "shell" 4) "vim" 5) "git" 6) "redis" #-------------------------------------------------- # 命令及描述 # 向有序集合添加一个或多个成员,或者更新已存在成员的分数 ZADD key score1 member1 [score2 member2] # 获取有序集合的成员数 ZCARD key # 计算在有序集合中指定区间分数的成员数 ZCOUNT key min max # 有序集合中对指定成员的分数加上增量 increment ZINCRBY key increment member # 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中 ZINTERSTORE destination numkeys key [key ...] # 在有序集合中计算指定字典区间内成员数量 ZLEXCOUNT key min max # 通过索引区间返回有序集合指定区间内的成员 ZRANGE key start stop [WITHSCORES] # 通过字典区间返回有序集合的成员 ZRANGEBYLEX key min max [LIMIT offset count] # 通过分数返回有序集合指定区间内的成员 ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] # 返回有序集合中指定成员的索引 ZRANK key member # 移除有序集合中的一个或多个成员 ZREM key member [member ...] # 移除有序集合中给定的字典区间的所有成员 ZREMRANGEBYLEX key min max # 移除有序集合中给定的排名区间的所有成员 ZREMRANGEBYRANK key start stop # 移除有序集合中给定的分数区间的所有成员 ZREMRANGEBYSCORE key min max # 返回有序集中指定区间内的成员,通过索引,分数从高到低 ZREVRANGE key start stop [WITHSCORES] # 返回有序集中指定分数区间内的成员,分数从高到低排序 ZREVRANGEBYSCORE key max min [WITHSCORES] # 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 ZREVRANK key member # 返回有序集中,成员的分数值 ZSCORE key member # 计算给定的一个或多个有序集的并集,并存储在新的 key 中 ZUNIONSTORE destination numkeys key [key ...] # 迭代有序集合中的元素(包括元素成员和元素分值) ZSCAN key cursor [MATCH pattern] [COUNT count]
在远程服务上执行命令
[root@WaWen /usr/local/redis/bin]#./redis-cli -h host -p port -a password
redis keys命令
# 命令及描述
# 该命令用于在 key 存在时删除 key。
DEL key
# 序列化给定 key ,并返回被序列化的值。
DUMP key
# 检查给定 key 是否存在。
EXISTS key
# 为给定 key 设置过期时间,以秒计。
EXPIRE key seconds
# EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
EXPIREAT key timestamp
# 设置 key 的过期时间以毫秒计。
PEXPIRE key milliseconds
# 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
PEXPIREAT key milliseconds-timestamp
# 查找所有符合给定模式( pattern)的 key 。
KEYS pattern
# 将当前数据库的 key 移动到给定的数据库 db 当中。
MOVE key db
# 移除 key 的过期时间,key 将持久保持。
PERSIST key
# 以毫秒为单位返回 key 的剩余的过期时间。
PTTL key
# 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
TTL key
# 从当前数据库中随机返回一个 key 。
RANDOMKEY
# 修改 key 的名称
RENAME key newkey
# 仅当 newkey 不存在时,将 key 改名为 newkey 。
RENAMENX key newkey
# 迭代数据库中的数据库键。
SCAN cursor [MATCH pattern] [COUNT count]
# 返回 key 所储存的值的类型。
TYPE key
redis 事务
redis事务能够一次执行多个命令,且有以下效果:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
127.0.0.1:6379> multi # 启动事务
OK
127.0.0.1:6379> set user "wawen 20 man"
QUEUED # 标识此时在队列中
127.0.0.1:6379> get user
QUEUED
127.0.0.1:6379> sadd students "ayu" "tulv" "yanwen" "huoshen" "niba" "ahao" "along" "wawen"
QUEUED
127.0.0.1:6379> smembers students
QUEUED
127.0.0.1:6379> exec # 开始执行
1) OK
2) "wawen 20 man"
3) (integer) 8
4) 1) "along"
2) "ahao"
3) "tulv"
4) "huoshen"
5) "wawen"
6) "ayu"
7) "niba"
8) "yanwen"
#--------------------------------------------------
# 命令及描述
# 取消事务,放弃执行事务块内的所有命令。
DISCARD
# 执行所有事务块内的命令。
EXEC
# 标记一个事务块的开始。
MULTI
# 取消 WATCH 命令对所有 key 的监视。
UNWATCH
# 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
WATCH key [key ...]
redis geo
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。
Redis GEO 操作方法
- geoadd:添加地理位置的坐标。
- geopos:获取地理位置的坐标。
- geodist:计算两个位置之间的距离。
- georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
- georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
- geohash:返回一个或多个位置对象的 geohash 值。
# getadd key longitude(经度) latitude(纬度) member(位置名称) [longitude latitude member ...]
127.0.0.1:6379> geoadd geo 12 14 "test1" 16 18 "test2" 39 45 "test3"
(integer) 3
127.0.0.1:6379> geoadd geo 15 34 "test4"
(integer) 1
# geopos key member [member ...]
127.0.0.1:6379> geopos geo test1 test2 test3 test4
1) 1) "12.00000196695327759"
2) "13.99999876480465133"
2) 1) "16.00000172853469849"
2) "17.99999913609774893"
3) 1) "38.99999767541885376"
2) "45.00000100864581043"
4) 1) "14.99999910593032837"
2) "34.00000062127011091"
127.0.0.1:6379> geopos get test5
1) (nil)
# geodist key member1 member2 [m|km|ft|mi]
# 最后一个距离单位参数说明:
# m :米,默认单位。
# km :千米。
# mi :英里。
# ft :英尺。
127.0.0.1:6379> geodist geo test1 test2
"617044.7973"
redis stream
Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
# 向队列添加消息,如果指定队列不存在,则创建一个队列
XADD key ID field value [field value ...]
# 示例
127.0.0.1:6379> xadd mystream * name jiewen age 20
"1627104826870-0"
127.0.0.1:6379> xadd mystream * name lulu age 20
"1627104838837-0"
127.0.0.1:6379> xadd mystream * name lvlv age 20
"1627104862485-0"
# 获取消息列表
XRANGE key start end [COUNT count]
# 示例
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104826870-0"
2) 1) "name"
2) "jiewen"
3) "age"
4) "20"
2) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
3) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
127.0.0.1:6379> keys *
1) "list_1"
2) "hash_1"
3) "name"
4) "runoob"
5) "get"
6) "mystream"
7) "sadd_1"
8) "user"
9) "zass_1"
10) "zadd_1"
11) "students"
12) "geo"
127.0.0.1:6379> xadd mystream * name gou age 88
"1627105428522-0"
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104826870-0"
2) 1) "name"
2) "jiewen"
3) "age"
4) "20"
2) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
3) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
4) 1) "1627105428522-0"
2) 1) "name"
2) "gou"
3) "age"
4) "88"
# 删除消息
XDEL key ID [ID ...]
# 示例
127.0.0.1:6379> xdel mystream 1627105428522-0
(integer) 1
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104826870-0"
2) 1) "name"
2) "jiewen"
3) "age"
4) "20"
2) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
3) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
# 获取元素数量,即消息长度
XLEN key
# 示例
127.0.0.1:6379> xlen mystream
(integer) 3
# 对流进行修剪,限制长度(不是持久性限制,类似截取,超出部分进行删除),返回结果代表删除的数量
XTRIM key MAXLEN [~] count
# 示例
127.0.0.1:6379> xtrim mystream maxlen 2
(integer) 1
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
2) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
# 此操作演示此命令只是一次性限制长度,之后添加数据可超过最大长度4
127.0.0.1:6379> xtrim mystream maxlen 4
(integer) 0
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
2) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
127.0.0.1:6379> xadd mystream * name gougou age 20
"1627105642194-0"
127.0.0.1:6379> xadd mystream * name gougou age 30
"1627105646075-0"
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
2) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
3) 1) "1627105642194-0"
2) 1) "name"
2) "gougou"
3) "age"
4) "20"
4) 1) "1627105646075-0"
2) 1) "name"
2) "gougou"
3) "age"
4) "30"
127.0.0.1:6379> xadd mystream * name gougou age 40
"1627105667129-0"
127.0.0.1:6379> xrange mystream - +
1) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
2) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
3) 1) "1627105642194-0"
2) 1) "name"
2) "gougou"
3) "age"
4) "20"
4) 1) "1627105646075-0"
2) 1) "name"
2) "gougou"
3) "age"
4) "30"
5) 1) "1627105667129-0"
2) 1) "name"
2) "gougou"
3) "age"
4) "40"
127.0.0.1:6379> xlen mystream
(integer) 5
# 以阻塞或非阻塞方式获取消息列表
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
# count:数量
# milliseconds:可选,阻塞毫秒数,没有设置就是非阻塞模式
# key:队列名
# id:消息ID
# 从 Stream 头部读取两条消息
127.0.0.1:6379> XREAD COUNT 2 STREAMS mystream writers 0-0 0-0
1) 1) "mystream"
2) 1) 1) "1627104838837-0"
2) 1) "name"
2) "lulu"
3) "age"
4) "20"
2) 1) "1627104862485-0"
2) 1) "name"
2) "lvlv"
3) "age"
4) "20"
2) 1) "writers"
2) 1) 1) 1526985676425-0
2) 1) "name"
2) "Virginia"
3) "surname"
4) "Woolf"
2) 1) 1526985685298-0
2) 1) "name"
2) "Jane"
3) "surname"
4) "Austen"
redis 备份与恢复
-
备份
save用于创建当前数据库的备份。
# 该命令将在 redis 安装目录中创建dump.rdb文件。 127.0.0.1:6379> save OK # 不过我是以脚本的形式启动redis-cli,所以此备份文件和启动脚本在同一个目录下 [root@WaWen /start_redis]#ls dump.rdb redis-cli.sh redis-conf.sh redis-server.sh
-
恢复数据
只需要将备份文件(dump.rdb)移动到redis安装目录兵启动服务即可
127.0.0.1:6379> config get dir # 此命令可以获取启动目录 1) "dir" 2) "/start_redis"
-
Bgsave
创建 redis 备份文件也可以使用命令 BGSAVE,该命令在后台执行
127.0.0.1:6379> bgsave Background saving started
redis 管道技术
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:
-
客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
-
服务端处理命令,并将结果返回给客户端。
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
Java使用Redis
-
首先需要一个jedis.jar的驱动包,可以使用一下依赖方便一点
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency>
-
需要确保redis的配置文件满足以下要求
# redis.conf # 以下绑定注释掉,不做连接要求 # bind 127.0.0.1 # 将protected-mode yes,修改为protected-mode no;不保护redis protected-mode no # 允许后台运行 daemonize yes # 我是使用的阿里云服务器,所以还需要配置一下安全组,允许端口号6379进行访问 # linux的防火墙允许设置端口6379进行通信 firewall-cmd --add-port=6379/tcp # 然后重启防火墙,使修改生效 firewall-cmd --reload # 当然在java连接之前得保证linux的redis服务端开启(本人写了一个简单的脚本启动redis服务器) #!/bin/bash /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
-
接下来进行java连接redis
public class RedisJava { public static void main(String[] args) { Jedis jedis = new Jedis("47.98.xxx.xxx");// 将ip填入,本机可填写"localhost" jedis.auth("123");// 输入redis密码(如果没有密码可以跳过这一步) System.out.println(jedis.ping());// 此语句入打印出PONG则代表链接成功 // 开始愉快的玩耍吧 jedis.set("name","wawen"); Map<String, String> object = new HashMap<>(); object.put("name1","1"); object.put("name2","2"); object.put("name3","3"); jedis.hmset("hmset_1", object); jedis.hmget("hmset_1","name1","name2","name3"); } }
基本的redis操作差不多就到这里了,学习不需要死记硬背,实践是检验真理的唯一标准。