redis介绍与数据类型
目前数据库分:关系型数据库与非关系型数据库
常用的关系型数据库: Oracle,MySQL,SqlServer,DB2
常用的非关系数据库:Redis,MongoDB,ElasticSearch, Hbase,Neo4j
那啥是非关系数据库呢?此处涉及到新名词:NoSQL
NoSQL最常见的解释是"non-relational", "Not Only SQL"也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。
如商城网站中对商品数据频繁查询、对热搜商品的排行统计、订单超时问题、以及微信朋友圈音频、视频存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。NoSQL这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。
分类 | 举例 | 典型应用场景 | 数据模型 | 优点 | 缺点 |
---|---|---|---|---|---|
键值(key-value)存储数据库 | redis | 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等。 | 通常用HashTable来实现 | 查找速度快 | 数据无结构化 |
列存储数据库 | HBase | 分布式的文件系统 | 将同一列数据存在一起 | 查找速度块,更容易进行分布式扩展 | 功能相对局限 |
文档型数据库 | MongoDB | 查询性能不高,且缺乏统一的查询语法 | |||
图形数据库 | Infinite Graph | 社交网络,专注于构建关系图谱 | 图结构 | 利用图数据结构相关算法 | 对整个图进行计算才能得到需要的信息 |
redis是以key-value形式存储,和传统的关系型数据库不一样。不一定遵循传统数据库的一些基本要求。
优点:
缺点:
redis 定位是缓存,提高数据读写速度,减轻对数据库存储和访问压力。redis是一个内存型的数据库
任务队列,如秒杀、抢购、购票排队等
即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息
为热点数据加速查询(主要场景),如热点商品、热点新闻
消息队列、分布式锁
redis 在线入门 : http://try.redis.io/
redis 中文资料官网: http://www.redis.cn/
redis官网:https://redis.io/download/
傻瓜式安装,一直下一步就可以了,注意要添加到环境变量中
默认端口:
最大内存
测试是否成功:
win+r
输入 redis-cli
AnotherRedisDesktopManager
工具可以用来可视化管理redis,可以理解为 MySQL的 Sqlyog、Navicat等管理工具。
下载完成后安装即可:
将其上传至 Linux 服务器目录下 /www/server/redis
中,并进行解压。
我这里使用 wget
命令下载,和上述步骤作用一致
# 进入/www/server/redis目录下载
wget https://github.com/redis/redis/archive/7.2.3.tar.gz
http://github.com/redis/redis/archive/7.2.3.tar.gz
# 解压
tar -zxvf 7.2.3.tar.gz
# 进入到解压目录
cd redis-7.2.3/
# 执行编译命令
make
# 安装,默认是安装到 /usr/local/bin 目录
make install
共安装了三个组件:redis server服务器、redis-cli客户端与一个性能测试工具 benchmark
vi /etc/systemd/system/redis.service
内容如下:
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /www/server/redis/redis-7.2.3/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
/www/server/redis/redis-7.2.3
,先拷贝redis.conf
,然后进行修改# 拷贝
cp redis.conf redis.conf.back
修改redis.conf
的配置
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
systemctl daemon-reload
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
systemctl enable redis
# 查看服务端版本
redis-server -v
# 查看客户端版本
redis-cli -v
在 /usr/local/bin
目录中,可以看到如下文件:
redis-serve
: 服务器启动命令redis-cli
: 命令行客户端redis-benchmark
: redis 性能测试工具redis-check-aof
:AOF文件修复工具redis-check-dump
:RDB文件检查工具(快照持久化文件)通过echo $PATH
可以看到,/usr/local/bin
目录是存在于该系统变量中的,这样这些命令就可以在任意目录中执行了,这就是为什么我们在任意目录都可以直接使用redis-cli
进行命令行
redis-server
这种启动属于前台启动
,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C
则Redis停止。不推荐使用。
方式二:指定配置文件启动,如果要让Redis以后台
方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/www/server/redis/redis-7.2.3
),名字叫redis.conf
我们先将这个配置文件备份一份:
cp redis.conf redis.conf.back
然后修改redis.conf文件中的一些配置:
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 1234
Redis的其它常见配置:
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志.持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
启动Redis:
# 进入redis安装目录
cd /www/server/redis/redis-7.2.3
# 启动
redis-server redis.conf
停止redis
# 利用redis-cli来执行 shutdown 命令,即可停止 Redis 服务,
# 因为之前配置了密码,因此需要通过 -u 来指定密码
redis-cli -u 1234 shutdown
方式三是开机自启,已经在2.2目录进行了设置
当给
redis.conf
设置了密码requirepass 1234
,则启动时需要auth 1234
Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:
redis-cli [options] [commonds]
其中常见的options有:
-h 127.0.0.1
:指定要连接的redis节点的IP地址,默认是127.0.0.1-p 6379
:指定要连接的redis节点的端口,默认是6379-a 1234
:指定redis的访问密码其中的commonds就是Redis的操作命令,例如:
ping
:与redis服务端做心跳测试,服务端正常会返回pong
进去下载 exe 文件即可
注意:在连接的时候请确保服务器的防火墙端口打开
6379
,否则会连接不上
Redis支持的存储数据类型有很多:
常用:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)
不常用:HyperLogLog,Bitmap(位图),Bloom Filter(布隆过滤器),Geospatial(地理位置) ,Module(模块), Streams(流信息)
命令格式
类型命令 | key | value |
---|---|---|
set | name | zhangsan |
操作建议
Redis操作有点类似Java的Map集合,都是key-value形式存储数据,在学习过程中,可以进行类比。
另外Redis中的key大部分为String类型,value值根据缓存数据结构可以选用:string,hash,list,set,zset等类型。
注意:下面讲的各种类型,表述的是缓存数据的value类型。
String类型包含多种类型的特殊类型,并且是二进制安全的,其值可以是数值,可以是字符串,也可以是二进制数据。
命令格式 | 功能 | 案例 | 说明 |
---|---|---|---|
set key value | 将key-value缓存redis中 | set name qxl | 设置name字段为qxl |
get key | 从redis中获取key对应value值 | get name | 获取name字段对应的value |
incr key | 将key对应value值 + 1 | incr age | 给age字段+1 |
decr key | 将key对应value值-1 | decr age | 给age字段-1 |
setex key seconds value | 将key-value缓存到redis中,seconds 秒后失效 | setex sex 10 man | 将sex字段设置为10s的man |
ttl key | 查看key存活时间 | ttl sex | 查看sex字段对应的 value 存活时间 |
del key | 从redis中删除key | del name | 删除name字段 |
setnx key value | 如果key已经存,不做任何操作,如果key不存,直接添加 | setnx name xiaofei |
普通字符串的基本操作:
# 设置 key-value 类型的值
> SET name lin
OK
# 根据 key 获得对应的 value
> GET name
"lin"
# 判断某个 key 是否存在
> EXISTS name
(integer) 1
# 返回 key 所储存的字符串值的长度
> STRLEN name
(integer) 3
# 删除某个 key 对应的值
> DEL name
(integer) 1
命令格式 | 功能 | 案例 |
---|---|---|
incrby key increment | 给key对应值加increment | incrby age 10 |
mset k1 v1 k2 v2… | 批量添加k1v1 k2v2 key value对 | mset name dafei age 18 |
mget k1 k2… | 批量获取k1, k2的值 | mget name age |
append key value | 在key对应的value值中拼+value | append name yes |
setrange key offset value | 修改key对应的value值,替换为指定value,冲offset索引位置开始 | setrange name 2 xx |
批量设置:
# 批量设置 key-value 类型的值
> MSET key1 value1 key2 value2
OK
# 批量获取多个 key 对应的 value
> MGET key1 key2
1) "value1"
2) "value2"
计数器(字符串的内容为整数的时候可以使用):
# 设置 key-value 类型的值
> SET number 0
OK
# 将 key 中储存的数字值增一
> INCR number
(integer) 1
# 将key中存储的数字值加 10
> INCRBY number 10
(integer) 11
# 将 key 中储存的数字值减一
> DECR number
(integer) 10
# 将key中存储的数字值键 10
> DECRBY number 10
(integer) 0
过期(默认为永不过期):
# 设置 key 在 60 秒后过期(该方法是针对已经存在的key设置过期时间)
> EXPIRE name 60
(integer) 1
# 查看数据还有多久过期
> TTL name
(integer) 51
#设置 key-value 类型的值,并设置该key的过期时间为 60 秒
> SET key value EX 60
OK
> SETEX key 60 value
OK
不存在就插入:
# 不存在就插入(not exists)
>SETNX key value
(integer) 1
缓存对象:使用 String 来缓存对象有两种方式:
SET user:1 '{"name":"xiaolin", "age":18}'
。MSET user:1:name xiaolin user:1:age 18 user:2:name xiaomei user:2:age 20
。主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量。这就是常规计数,计算访问次数、点赞次数、转发次数等。
共享session:
通常我们在开发后台管理系统时,会使用 Session 来保存用户的会话(登录)状态,这些 Session 信息会被保存在服务器端,但这只适用于单系统应用,如果是分布式系统此模式将不再适用。
例如用户一的 Session 信息被存储在服务器一,但第二次访问时用户一被分配到服务器二,这个时候服务器并没有用户一的 Session 信息,就会出现需要重复登录的问题,问题在于分布式系统每次会把请求随机分配到不同的服务器。
Hash 是一个键值对(key - value)集合,其中 value 的形式如: value=[{field1,value1},...{fieldN,valueN}]
。Hash类型特别适合存储对象:
类似Java中:Map<String, Map<String, ?>> map
Hash 类型的底层数据结构是由压缩列表或哈希表实现的:
512
个,所有值小于 64
字节的话,Redis 会使用压缩列表作为 Hash 类型的底层数据结构;在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。
命令格式 | 功能 | 案例 | 说明 |
---|---|---|---|
hset key field value | 将field value对缓存到redis中hash中,键值为key | hset user name dafei | 给user中的name字段设置为dafei |
hget key field | 从key对应hash列表中获取field字段 | hget user name | 获取user中的name字段 |
hexists key field | 判断key对应的hash列表是否存在 field字段 | hexists user age | 判断user中是否存在age字段 |
hdel key field | 删除key对应hash列表中field字段 | hdel user age | 删除user中的age字段 |
hincrby key field increment | 给key对应hash列表中field字段 + increment | hincrby user age 10 | 给user中的age字段+10 |
hlen key | 查看key对应的hash列表field的数量 | hlen user | 查看user中的所有 key |
hkeys key | 获取key对应的hash列表所有的field值 | hkeys user | 获取user中的所有 key |
hvals key | 获取key对应的hash列表所有的field对应的value值 | hvals user | 获取user中的所有value |
hgetall key | 获取key对应的hash列表中所有的field及其对应的value值 | hgetall user | 获取user中的所有 key 和 value |
# 存储一个哈希表key的键值
HSET key field value
# 获取哈希表key对应的field键值
HGET key field
# 在一个哈希表key中存储多个键值对
HMSET key field value [field value...]
# 批量获取哈希表key中多个field键值
HMGET key field [field ...]
# 删除哈希表key中的field键值
HDEL key field [field ...]
# 返回哈希表key中field的数量
HLEN key
# 返回哈希表key中所有的键值
HGETALL key
# 为哈希表key中field键的值加上增量n
HINCRBY key field n
Hash类型数据操作的注意事项:
- Hash类型下的 value 只能存储字符串,不允许存储其他数据类型
- Hash设计的初衷不是为了存储大量对象的,切记不可滥用。
缓存对象:Hash 类型的 (key,field, value) 的结构与对象的(对象id, 属性, 值)的结构相似,也可以用来存储对象。我们以用户信息为例,它在关系型数据库中的结构是这样的:
uid | name | age |
---|---|---|
1 | Tom | 15 |
2 | Jerry | 13 |
我们可以使用如下命令,将用户对象的信息存储到 Hash 类型:
# 存储一个哈希表uid:1的键值
> HMSET uid:1 name Tom age 15
2
# 存储一个哈希表uid:2的键值
> HMSET uid:2 name Jerry age 13
2
# 获取哈希表用户id为1中所有的键值
> HGETALL uid:1
1) "name"
2) "Tom"
3) "age"
4) "15
一般对象用 String + Json 存储,对象中某些频繁变化的属性可以考虑抽出来用 Hash 类型存储。
电商网站购物车设计
以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息。将商品编号作为field,购买数量作为value进行存储
key | value |
---|---|
id | { name: dafei field:001 value:3 } |
添加购物车:追加全新的field与value
浏览购物车:遍历hash
更改购物车数量:自增/自减,设置value值
删除购物车商品:删除field
清空购物车:删除key
512
个,列表每个元素的值都小于 64
字节,Redis 会使用压缩列表作为 List 类型的底层数据结构;但是在 Redis 3.2 版本之后,List 数据类型底层数据结构就只由 quicklist 实现了,替代了双向链表和压缩列表
命令格式 | 功能 | 案例 | 说明 |
---|---|---|---|
rpush key value | 从右边往key集合中添加value值 | rpush hobby java | 从右边向 hobby 集合中添加 java 字段 |
lrange key start stop | 从左边开始列表key集合,从start位置开始,stop位置结束 | lrange hobby 0 3 lrange hobby 0 -1 | 从左边开始罗列 hobby 集合下标 0-3 的字段 从左边开始罗列 hobby 集合下所有字段 |
lpush key value | 从左边往key集合中添加value值 | lpush hobby c++ | 从左边向 hobby 集合中添加 c++ 字段 |
lpop key | 弹出key集合中最左边的数据 | lpop hobby | 弹出 hobby 集合中最左边的数据 |
rpop key | 弹出key集合中最右边的数据 | rpop hobby | 弹出 hobby 集合中最右边的数据 |
llen key | 获取列表长度 | llen hooby | 获取 hobby 集合的长度 |
# 将一个或多个值value插入到key列表的表头(最左边),最后的值在最前面
LPUSH key value [value ...]
# 将一个或多个值value插入到key列表的表尾(最右边)
RPUSH key value [value ...]
# 移除并返回key列表的头元素
LPOP key
# 移除并返回key列表的尾元素
RPOP key
# 返回列表key中指定区间内的元素,区间以偏移量start和stop指定,从0开始
LRANGE key start stop
# 从key列表表头弹出一个元素,没有就阻塞timeout秒,如果timeout=0则一直阻塞
BLPOP key [key ...] timeout
# 从key列表表尾弹出一个元素,没有就阻塞timeout秒,如果timeout=0则一直阻塞
BRPOP key [key ...] timeout
命令格式 | 功能 | 案例 |
---|---|---|
linsert key before pivot value | 操作key集合,在pivot值之前插入value | linsert hobby before java c# |
linsert key after pivot value | 操作key集合,在pivot值之后插入value | linsert hobby after java c# |
lset key index value | 操作key集合,更新索引index位置值为value | lset hobby 1 go |
lrem key count value | 操作key集合,删除 count个 value值 | lrem hobby 3 go |
ltrim key start stop | 操作key集合,从start到stop截取自列表 | ltrim hobby 2 4 |
lindex key index | 操作key集合,获取索引为index位置的数据 | lindex hobby 1 |
key | value |
---|---|
user_favor_article_list | [aid1, aid2, aid3…] |
Set 类型是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储。
Set 类型和 List 类型的区别如下:
Set 类型的底层数据结构是由哈希表或整数集合实现的:
512
(默认值,set-maxintset-entries
配置)个,Redis 会使用整数集合作为 Set 类型的底层数据结构;命令格式 | 功能 | 案例 | 说明 |
---|---|---|---|
sadd key members […] | 往key 集合中添加member元素 | sadd myset a b c | 给集合 myset 添加 a b c 元素 |
smembers key | 遍历key集合中所有的元素 | smembers myset | 遍历集合 myset |
srem key members […] | 删除key集合中members元素 | srem myset a | 删除myset集合中的元素a |
spop key count | 从key集合中随机弹出count个元素 | spop myset 1 |
# 往集合key中存入元素,元素存在则忽略,若key不存在则新建
SADD key member [member ...]
# 从集合key中删除元素
SREM key member [member ...]
# 获取集合key中所有元素
SMEMBERS key
# 获取集合key中的元素个数
SCARD key
# 判断member元素是否存在于集合key中
SISMEMBER key member
# 从集合key中随机选出count个元素,元素不从key中删除
SRANDMEMBER key [count]
# 从集合key中随机选出count个元素,元素从key中删除
SPOP key [count]
命令格式 | 功能 | 案例 |
---|---|---|
sdiff key1 key2 | 返回key1中特有的元素(差集) | sdiff key1 key2 |
sidiffstore dest key1 key2 | 返回key1中特有的元素,并将返回值缓存到dest集合中 | sidiffstore dest key1 key2 |
sinter key1 key2 | 返回key1跟key2集合的交集 | sinter key1 key2 |
sinterstore dest key1 key2 | 返回key1跟key2集合的交集,并将返回值缓存到dest集合中 | sinterstore dest key1 key2 |
sunion key1 key2 | 返回key1跟key2集合的并集 | sunion key1 key2 |
sunionstore dest key1 key2 | 返回key1跟key2集合的并集,并将返回值缓存到dest集合中 | sunionstore dest key1 key2 |
smove source destination member | 将source集合中member元素移动到destination集合中 | smove key1 key2 aa |
sismember key member | 判断member元素是否在key集合中 | sismember key1 aa |
srandmember key count | 随机获取set集合中count 个元素 | srandmem |
# 交集运算
SINTER key [key ...]
# 将交集结果存入新集合destination中
SINTERSTORE destination key [key ...]
# 并集运算
SUNION key [key ...]
# 将并集结果存入新集合destination中
SUNIONSTORE destination key [key ...]
# 差集运算
SDIFF key [key ...]
# 将差集结果存入新集合destination中
SDIFFSTORE destination key [key ...]
集合的主要几个特性,无序、不可重复、支持并交差等操作。因此 Set 类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集合的交集、错集和并集等,当我们存储的数据是无序并且需要去重的情况下,比较适合使用集合类型进行存储。
Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞
在主从集群中,为了避免主库因为 Set 做聚合计算(交集、差集、并集)时导致主库被阻塞,我们可以选择一个从库完成聚合统计,或者把数据返回给客户端,由客户端来完成聚合统计。
点赞场景:Set 类型可以保证一个用户只能点一个赞,这里举例子一个场景,key 是文章id,value 是用户id。
# uid:1 、uid:2、uid:3 三个用户分别对 article:1 文章点赞了
# uid:1 用户对文章 article:1 点赞
> SADD article:1 uid:1
(integer) 1
# uid:2 用户对文章 article:1 点赞
> SADD article:1 uid:2
(integer) 1
# uid:3 用户对文章 article:1 点赞
> SADD article:1 uid:3
(integer) 1
# uid:1 取消了对 article:1 文章点赞。
> SREM article:1 uid:1
(integer) 1
# 获取 article:1 文章所有点赞用户
> SMEMBERS article:1
1) "uid:3"
2) "uid:2"
# 获取 article:1 文章的点赞用户数量
> SCARD article:1
(integer) 2
# 判断用户 uid:1 是否对文章 article:1 点赞了
> SISMEMBER article:1 uid:1
(integer) 0 # 返回0说明没点赞,返回1则说明点赞了
共同关注:Set 类型支持交集运算,所以可以用来计算共同关注的好友、公众号等
# key 可以是用户id,value 则是已关注的公众号的id。
# uid:1 用户关注公众号 id 为 5、6、7、8、9,uid:2 用户关注公众号 id 为 7、8、9、10、11
# uid:1 用户关注公众号 id 为 5、6、7、8、9
> SADD uid:1 5 6 7 8 9
(integer) 5
# uid:2 用户关注公众号 id 为 7、8、9、10、11
> SADD uid:2 7 8 9 10 11
(integer) 5
# 获取共同关注
> SINTER uid:1 uid:2
1) "7"
2) "8"
3) "9"
# 给 uid:2 推荐 uid:1 关注的公众号
> SDIFF uid:1 uid:2
1) "5"
2) "6"
# 验证某个公众号是否同时被 uid:1 或 uid:2 关注:
> SISMEMBER uid:1 5
(integer) 1 # 返回0,说明关注了
> SISMEMBER uid:2 5
(integer) 0 # 返回0,说明没关注
抽奖活动:存储某活动中中奖的用户名 ,Set 类型因为有去重功能,可以保证同一个用户不会中奖两次
# key为抽奖活动名,value为员工名称,把所有员工名称放入抽奖箱
>SADD lucky Tom Jerry John Sean Marry Lindy Sary Mark
(integer) 5
# 如果允许重复中奖,可以使用 SRANDMEMBER 命令
# 抽取 1 个一等奖:
> SRANDMEMBER lucky 1
1) "Tom"
# 抽取 2 个二等奖:
> SRANDMEMBER lucky 2
1) "Mark"
2) "Jerry"
# 抽取 3 个三等奖:
> SRANDMEMBER lucky 3
1) "Sary"
2) "Tom"
3) "Jerry"
如果不允许重复中奖,可以使用 SPOP 命令
# 抽取一等奖1个
> SPOP lucky 1
1) "Sary"
# 抽取二等奖2个
> SPOP lucky 2
1) "Jerry"
2) "Mark"
# 抽取三等奖3个
> SPOP lucky 3
1) "John"
2) "Sean"
3) "Lindy"
Zset 类型的底层数据结构是由压缩列表或跳表实现的:
128
个,并且每个元素的值小于 64
字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构;在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。
命令格式 | 功能 | 案例 | 说明 |
---|---|---|---|
zadd key score member | 往key集合中添加member元素,分数为score | zadd players 100 a | 向players集合添加a元素,分数为100 |
zincrby key increment member | 将key集合中的member元素 分数 + increment | zadd players 100 a | 向players集合的a元素分数+100 |
zrange key start stop [withscores] | 将key集合中的元素按分数升序排列 [显式分数] | zrange players 0 -1 withscores | |
zrevrange key start stop [withscores] | 将key集合中的元素按分数降序排列 [显式分数] | zrevrange players 0 -1 withscores | |
zrank key member | 返回member元素在key结合中的正序排名 | zrank players a | 返回players集合中a元素的正序排名 |
zrevrank key member | 返回member元素在key结合中的倒序排名 | zrevrank players a | |
zcard key | 返回key集合元素个数 | zcard players |
# 往有序集合key中加入带分值元素
ZADD key score member [[score member]...]
# 往有序集合key中删除元素
ZREM key member [member...]
# 返回有序集合key中元素member的分值
ZSCORE key member
# 返回有序集合key中元素个数
ZCARD key
# 为有序集合key中元素member的分值加上increment
ZINCRBY key increment member
# 正序获取有序集合key从start下标到stop下标的元素
ZRANGE key start stop [WITHSCORES]
# 倒序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]
# 返回有序集合中指定分数区间内的成员,分数由低到高排序。
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
# 返回指定成员区间内的成员,按字典正序排列, 分数必须相同。
ZRANGEBYLEX key min max [LIMIT offset count]
# 返回指定成员区间内的成员,按字典倒序排列, 分数必须相同
ZREVRANGEBYLEX key max min [LIMIT offset count]
Zset 运算操作(相比于 Set 类型,ZSet 类型没有支持差集运算):
# 并集计算(相同元素分值相加),numberkeys一共多少个key,WEIGHTS每个key对应的分值乘积
ZUNIONSTORE destkey numberkeys key [key...]
# 交集计算(相同元素分值相加),numberkeys一共多少个key,WEIGHTS每个key对应的分值乘积
ZINTERSTORE destkey numberkeys key [key...]
命令格式 | 功能 | 案例 |
---|---|---|
zrangebyscore key min max [withscores] | 按[min, max) 分数范围返回key集合中元素(正序) | zrangebyscore players 200 300 withscores |
zrevrangebyscore key min max [withscores] | 按[min, max) 分数范围返回key集合中元素(倒序) | zrevrangebyscore players 200 300 withscores |
zrem key member | 删除key集合中member元素与分数 | zrem players a |
zremrangebyscore key min max withscores | 按[min, max) 分数范围删除key集合中元素 | zremrangebyscore players 200 300 withscores |
zremrangebyrank key start stop | 删除key集合正序排名落在[start, stop) 范围元素 | zremrangebyrank players 10 20 |
zcount key min max | 按照分数范围[min, max]统计key集合中元素个数 | zcount players 100 300 |
? Zset 类型(Sorted Set,有序集合) 可以根据元素的权重来排序,我们可以自己来决定每个元素的权重值。比如说,我们可以根据元素插入 Sorted Set 的时间确定权重值,先插入的元素权重小,后插入的元素权重大。
? 在面对需要展示最新列表、排行榜等场景时,如果数据更新频繁或者需要分页显示,可以优先考虑使用 Sorted Set。
排行榜:我们以博文点赞排名为例,小林发表了五篇博文,分别获得赞为 200、40、100、50、150。
# arcticle:1 文章获得了200个赞
> ZADD user:xiaolin:ranking 200 arcticle:1
(integer) 1
# arcticle:2 文章获得了40个赞
> ZADD user:xiaolin:ranking 40 arcticle:2
(integer) 1
# arcticle:3 文章获得了100个赞
> ZADD user:xiaolin:ranking 100 arcticle:3
(integer) 1
# arcticle:4 文章获得了50个赞
> ZADD user:xiaolin:ranking 50 arcticle:4
(integer) 1
# arcticle:5 文章获得了150个赞
> ZADD user:xiaolin:ranking 150 arcticle:5
(integer) 1
文章 arcticle:4 新增一个赞,可以使用 ZINCRBY 命令(为有序集合key中元素member的分值加上increment):
> ZINCRBY user:xiaolin:ranking 1 arcticle:4
"51"
查看某篇文章的赞数,可以使用 ZSCORE 命令(返回有序集合key中元素个数):
> ZSCORE user:xiaolin:ranking arcticle:4
"50"
获取小林文章赞数最多的 3 篇文章,可以使用 ZREVRANGE 命令(倒序获取有序集合 key 从start下标到stop下标的元素):
# WITHSCORES 表示把 score 也显示出来
> ZREVRANGE user:xiaolin:ranking 0 2 WITHSCORES
1) "arcticle:1"
2) "200"
3) "arcticle:5"
4) "150"
5) "arcticle:3"
6) "100"
获取小林 100 赞到 200 赞的文章,可以使用 ZRANGEBYSCORE 命令(返回有序集合中指定分数区间内的成员,分数由低到高排序):
> ZRANGEBYSCORE user:xiaolin:ranking 100 200 WITHSCORES
1) "arcticle:3"
2) "100"
3) "arcticle:5"
4) "150"
5) "arcticle:1"
6) "200"
Redis 的key 设计讲究4个性:
Redis 类似Map集合,key必须保证唯一,缓存同一个key时,后者会覆盖前者,所以必须要求唯一,那如何保证唯一呢?最常用的方式:使用缓存数据的主键作为key。
比如:缓存员工信息
key | value |
---|---|
1 | 员工1 |
2 | 员工2 |
其中的1, 2 是员工的id
可读性是保证Redis的key能做到见名知意,上面的员工id1, 员工id2 虽说能保证key唯一,但可读性非常差,维护key时,无法从1, 2中快速判断该key对应value值。所以一一般在保证key唯一的前提下,给key加上前缀:
key | value |
---|---|
employee_info:id1 | 员工1 |
employee_info:id2 | 员工2 |
employee_info:id1
、 employee_info:id2
这样子设计key,可读性就好多了。
key | value |
---|---|
employee :base.info:id1:hash | 员工对象信息 |
业务模块名:表示该key属于哪个功能模块
业务逻辑含义段:这里可以使用 . 分开, 具体业务逻辑表示
employee:auth.permission:id1:set
员工权限集合其他:一般设置唯一标识,比如主键
value类型:key对应value类型值,提高可读性。
redis key一定要设置过期时间。要跟自己的业务场景,需要对key设置合理的过期时间。可以在写入key时,就要追加过期时间;也可以在按照需要动态设置。
这里要注意:
这个难介绍,一般key保证唯一时,可以使用主键,有的使用一个主键不能表达出全部意思,可以使用联合主键。
比如:id为1的朋友圈下id为A的评论。
key | value |
---|---|
post:1:reply:A | 评论内容 |
post:1:reply:B | 评论内容 |
下面我们将介绍两种常用的方法来为Redis设置密码:
在Redis的配置文件redis.conf
中,可以通过以下步骤来设置密码:
redis.conf
文件(我的是在./www/server/redis/redis-7.2.3
目录下)requirepass
项在requirepass
后面添加你想要设置的密码,如requirepass 1234
。
保存并关闭配置文件。
重新启动Redis服务器,使密码生效。
除了通过配置文件,还可以直接通过命令行来为Redis设置密码。打开终端并输入以下命令:
redis-cli
接着,在命令行中输入以下命令来设置密码:
config set requirepass mypassword
运行上述命令后,Redis将返回OK
表示密码设置成功。
验证:
auth mypassword
来验证密码OK
,表示密码验证成功。config set requirepass newpassword
替换newpassword
为你想要设置的新密码。
config set requirepass ""
运行上述命令后,Redis将返回OK
,表示密码已成功取消。
多,就容易达到服务器的内存上限,导致宕机,开发时一般配合Key过期策略使用哦。