Redis

1. 架构的演变

1.1 单体/库架构

90 年代开始,当时主流的技术是 JSP/HTML+Servlet+JDBC ,那个时候网站上基本的网站访问量都不会太大, 所以单机数据库就已经完全胜任。那个时代互联网刚刚发展! select * select 列名 where 条件要精准
架构的瓶颈:
1.数据量太大怎么办?
2.数据访问量太大怎么办? -- (读写混合)
3.当数据库单表数据超出千万级别,就必须需要创建索引,内存放不下怎么办?
1.2 缓存 + 读写分离 + 垂直拆分
单纯的实现了读写分离确实也解决了服务器压力,但是不足以胜任日益增长的访问量,然后我们将矛头指向了架构优化,如何优化

 

瓶颈:

用户量和数据量越来越大,即使我们通过读写分离和分库分表也不足以支撑的时候,单表数据量已经爆炸了。
1.3 分库分表 + 水平拆分 (MySQL 集群 )

 瓶颈:

10 年,是历史上科技发展最迅速的 10 年,我们的数据从简单的文字、图片也已经转变为各式各样的数据类型,那么传统的关系型数据库MySQL 已经不满足我们现在发展的需求。图片、热点数据、大篇幅文章、定位信息等各式各样的数据扑面而来!,那么就需要我们挨个解决,
如果有一个数据库能帮助我们分担这种特殊的数据,那么关系型数据库( MySQL Oracle )的压力也就会变小了。
同时数据的存储也从 IO 1+1  变成了  IO 1+N
1.4 当下互联网公司架构

那么我们对架构的分析,大家也了解到,目前互联网项目对于各式各样的数据我们 MySQL这种关系型数据库存储数据就显得特别疲惫,那么这个时候 NoSQL(非关系型)数据库就随之而来。

2. 关于NoSQL

NoSQL ----  错误翻译  没有 SQL
正确翻译: Not Only SQL (不仅仅是 SQL ) 泛指我们非关系数据库,主要适用于 web2.0 时代。

 2.1 区别

关系型:

 非关系型

典型的就是key-value形式进行存储数据,而且存储的类型也变得多样化,不再是单一的文字结构。

2.2 NoSQL 特点
1.扩展方便,数据与数据之间没有必然联系, 0 耦合。
2.大数据量和高性能( redis => 单秒写 10 万次 读取 11 万次) QPS
3. 数据类型的多样化( 5+3 String List Set Hash Zset | geo( 地理位置信息 ) hyperloglog (访 客信息)、 bitmap 位图 ( 常用计算活跃粉丝和不活跃粉丝、登录和未登录、是否打卡等 )
4.不需要提前设计数据库,随取随用。
2.3 淘宝架构分析

 商品基本信息 id、名称、分类基本信息

- MySQL | Oracle 淘宝是讲MySQL进行了开发,虽然都叫MySQL但是内容完全不同
2012年5月,淘宝做了一个艰难的决定,实行去IOE运动。这里的I是指IBM小型机,O指oracle数据库,E是指
EMC2是数据库的存储设备。而这一次的去IOE运动却恰恰是将亚洲亚洲最成功也是最大的oracle RAC应用的典范
转换为MYSQL +PC server,当然需要mysql的hadoop集群的架构。
商品的描述信息、评论等文字量较多的信息
MongoDB 文档型数据库
图片
 淘宝 - TFS 自主研发
 分布式系统 FastDFS
 Google - GFS 自主研发
 Hadoop -- HDFS
 阿里云 - OSS
商品的关键字 ( 搜索功能 )
 搜索引擎 solr elasticsearch --比较火
 淘宝自己使用 ISearch
热门的波段信息(秒杀)
 Redis Tair memacached
订单交易
第三方应用 MQ消息中间件 -- RabbitMQ
阿里的框架发展史 ( 强烈建议阅读 )
2.4 NoSQL 的四大类
KV类型
- 新浪 redis
- 美团 Redis + Tair
- 阿里、百度 redis + memcached

文档类型数据库(BSON 和 JSON一样)
- MongoDB (目前企业需求也是比较大的) 是一个给予分布式存储的数据库,主要用于处理大量的文档,
  是一个介于关系型和非关系型数据库的中间产品,本身属于非关系型。

列存储的数据库
- 大数据的HBase
- 分布式文件系统(一个业务分拆多个子业务,部署在不同的服务器上)

图形关系数据库
- 图示 - 存储的是图形关系,类似与朋友圈或社交平台
- Neo4J InfoGrid

3. redis介绍及安装

3.1 redis 介绍
Redis Remote Dictionary Server ) ,即远程字典服务,是一个开源的使用 ANSI C 语言编写、支持网络、可 基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API 。从 2010 3 15 日起, Redis 的开发工作由VMware 主持。从 2013 5 月开始, Redis 的开发由 Pivotal 赞助。
redis能做什么?
        1. 内存存储,持久化,断电即丢失,所以持久化很重要, redis 采用两种机制( RDB AOF
        2. 效率高,可以用于高速缓存
        
        3. 发布订阅系统
        
        4. 地图信息分析
        5. 计数器等,网站浏览量
redis特点/特性
        1. 多样的数据类型
        2. 持久化
        3. 集群
        4. 事务等 ...
3.2 Install redis in centos7
3.2.1 Install gcc
linux 中的 gcc 是由 GNU 推出的一款功能强大的、性能优越的多平台编译器。 gcc 编译器能将 C C++ 语言源程序和目标程序编译、连接成可执行文件。
因为 redis 依赖 c++ 环境 所以我们需要安装 c++
yum install gcc-c++
可以通过 gcc -v 检查版本
gcc -v
升级版本 因为 redis7.* 需要 gcc 高版本的支持 4 个分别执行
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
#修改使用版本
scl enable devtoolset-9 bash
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
继续查看 gcc 版本 升级到 9.* 完成安装
3.2.2 下载与安装 redis
redis 可以在 windows linux 下安装使用,但是 windows系统版本已经停更很长时间,不建议使用。 官网https://redis.io/   中文网http:// http://www.redis.cn/
通过工具将安装文件放在 opt 文件夹下:
注意:如果是系统应用如Java我们会安装到/usr/local 下, 如果是用户级的应用,我们就放在opt下

 解压文件夹:

 解压后进入redis文件夹查看文件:

 编译:会将需要的配置帮助我们配置完成

make #注意需要在解压后的redis文件夹中执行
这一步就是编译,大多数的源代码包都经过这一步进行编译(当然有些 perl python 编写的软件需要 调用perl python 来进行编译)。如果 在 make 过程中出现 error ,就要记下错误代码(注意不仅仅是最后一行),然后可以向开发者提交 bugreport (一般在 INSTALL 里有提交地址)。或者系统少了一些依赖库等,这些需要自己仔细研究错误代码。make 的作用是开始进行源代码编译,以及一些功能的提供,这些功能由他的 Makefile 设置文件提供相关的功能。比如 make install 一般表示进行安装,make uninstall 是卸载,不加参数就是默认的进行源代码编译。 make Linux 开发套件里面自动化编译的一个控制程序,他通过借助 Makefile 里面编写的编译规范进行自动化的调用 gcc ld 以及运行某些需要的程序进行编译的程序。
安装 redis
make install
这条命令来进行安装(当然有些软件需要先运行 make check make test 来进行一些测试),这一步一般需要你有 root 权限(因为要向系统写入文件)。
命令拓展 - 软件安装流程
1、解zhi包软件
tar zxf xxxx.tgz
2、配置
cd xxxx
./configure
3、编译
make
4、安装
make install
5、卸载
make uninstall
检查 redis 环境服务所在的位置
启动测试
redis-server
redis-server redis-config #后面是配置文件路径

 2.2.3 配置redis

安装 vim 编辑器
yum -y install vim*
备份文件
redis 配置文件的同级目录创建一个文件夹并且 cp 一个 redis.conf 文件到新的文件夹,
以后我们使用这个 cp 的文件进行操作,原生原件不变动。

修改后台启动 

vim redis-conf

 daemonize 默认值是no 修改yes 意思是以守护进程方式启动(后台运行)

重新启动 redis 并查看测试
[root@it-sunwz ~]# redis-server /opt/redis-6.0.6/it-sunwz/redis.conf
查看进程
ps -aux | grep redis
ps -ef | grep redis

 客户端连接测试

[root@it-sunwz ~]# redis-cli -h 127.0.0.1 -p 6379
[root@it-sunwz ~]# redis-cli -h 127.0.0.1 -p 6379 --raw #支持中文显示

 客户端IO测试

set name 张三
get name
keys *
退出客户端和结束服务
# 退出客户端
exit
# 结束服务方式1 客户端内直接输入 shutdown
shutdown
# 结束服务方式2 客户端外直接输入命令
redis-cli shutdown
防火墙命令拓展
启动防火墙:systemctl start firewalld
关闭防火墙:systemctl stop firewalld
检查防火墙状态:systemctl status firewalld
设置开机启用防火墙:systemctl enable firewalld.service
设置开机禁用防火墙:systemctl disable firewalld.service

关闭防火墙:systemctl stop firewalld
设置开机禁用防火墙:systemctl disable firewalld.service

2.2.4 redis开关

第一种:退出客户端之后
[root@sunwz ~]# redis-cli shutdown
第二种:直接在客户端内 ( 建议 )
127.0.0.1:6379>shutdown

3.3 redis可视化工具安装

Redis Desktop Manager(Redis可视化工具)安装及使用

 配置防火墙开放端口

firewall-cmd --add-port=6379/tcp --permanent
firewall-cmd --remove-port=8888/tcp --permanent
firewall-cmd --list-ports
redis 服务默认有保护机制,机制规则默认是只允许当前安装 redis 服务的电脑访问 127.0.0.1

 redis默认在配置文件中有一个Ip地址 绑定的就是127.0.0.1 ,需要我们注释掉这个地址才能支持远程访问。

 重新启动redis 服务

 

 4 .redis入门

4.1 关于 redis 线程问题
redis 的单线程的,那么单线程为什么还这么快?
Redis 的数据结构并不全是简单的 Key-Value ,还有 list hash 等复杂的结构。这些结构有可能会进行很细 粒度的操作,比如在很长的列表后面添加一个元素,在 hash 当中添加或者删除一个对象。这些操作可能就 需要加非常多的锁,导致的结果是同步开销大大增加。
总之,在单线程的情况下,代码更清晰,处理逻辑更简单,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗,不存在多进程或者多线程导致的切换而消耗 CPU
单线程多进程的集群方案
单线程的威力实际上非常强大,每核效率也非常高。多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。所以单线程、多进程的集群不失为一个时髦的解决方案。
CPU 消耗
采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU 。但是如果 CPU 成为 Redis 瓶颈,或者不想让服务器其他 CPU 核闲置,那怎么办?
可以考虑多起几个 Redis 进程, Redis key-value 数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些 key 放在哪个 Redis 进程上就可以了。

4.2 redis 基础命令

4.2.1 数据库切换操作
127.0.0.1:6379> PING #检查连接
PONG
127.0.0.1:6379> SELECT 15
OK
127.0.0.1:6379[15]> SELECT 16 #一共16个库 0-15
(error) ERR DB index is out of range
127.0.0.1:6379[15]> SELECT 0 #默认是0 不显示索引
OK
127.0.0.1:6379>

4.2.2 查看当前数据库

127.0.0.1:6379> SET student zhangsan #增加一个数据
OK
127.0.0.1:6379> SET student lisi #相同key增加一个数据 会覆盖掉
OK
127.0.0.1:6379> GET student # 取值
"lisi"
127.0.0.1:6379> KEYS * # 查看所有的key
1) "list11"
2) "student"
3) "user:1:age"
4) "user:1:name"
127.0.0.1:6379>

4.2.3 清除数据库中的数据

flushdb 删除当前库 -- 前提进入当前数据库中
flushall 删除所有库
127.0.0.1:6379> SET student zhangsan #在索引0库加信息
OK
127.0.0.1:6379> SET teacher lisi #在索引0库加信息
OK
127.0.0.1:6379> select 5 #切换索引为5的库
OK
127.0.0.1:6379[5]> SET user wangwu #在索引5库加信息
OK
127.0.0.1:6379[5]> KEYS *
1) "user"
127.0.0.1:6379[5]> FLUSHDB #清除当前库
OK
127.0.0.1:6379[5]> keys *
(empty array)
127.0.0.1:6379[5]> SELECT 0
OK
127.0.0.1:6379> KEYS *
4.2.4 设置过期时间
4.2.5 查看key类型
4.2.5 查看key是否存在
5. redis数据类型
redis存在5种基本数据类型和三种特殊类型
1) "teacher"
2) "student"
127.0.0.1:6379> SELECT 5
OK
127.0.0.1:6379[5]> FLUSHALL #清空所有的库信息
OK
127.0.0.1:6379[5]> SELECT 0
OK
127.0.0.1:6379> KEYS *
(empty array)
127.0.0.1:6379>

4.2.4 设置过期时间

127.0.0.1:6379> set student jiazong
OK
127.0.0.1:6379> EXPIRE student 30 #设置过期 秒数
(integer) 1
127.0.0.1:6379> TTL student
(integer) 18
127.0.0.1:6379> TTL student
(integer) 16
127.0.0.1:6379> TTL student #查看过期时间
(integer) 14
127.0.0.1:6379> TTL student
(integer) 7
127.0.0.1:6379> TTL student
(integer) -2
127.0.0.1:6379> get student
(nil)
127.0.0.1:6379>

4.2.5 查看key类型

type key
4.2.5 查看 key 是否存在
EXISTS key

5. redis数据类型

redis 存在 5 种基本数据类型和三种特殊类型

5.1 String类型

例举:分布式锁、 Session 相关、验证码相关、计数相关 ( 点击量 / 阅读量 / 关注 ) 等单一的值。

5.1.1 取值赋值

关键词: set get append strlen
127.0.0.1:6379> set stu1 zhangsan ##基本使用设置值
OK
127.0.0.1:6379> get stu1
"zhangsan"
127.0.0.1:6379> APPEND stu1 shigehaoren ##追加值
(integer) 19
127.0.0.1:6379> get stu1
"zhangsanshigehaoren"
127.0.0.1:6379> STRLEN stu1 ##获取字符串长度
(integer) 19
127.0.0.1:6379>

5.1.2 加减操作

increment 自增1 decrement 自减
incrby 固定增量 自定义
decrby 固定减量 自定义
##值++
incr key
##值--
decr key
##增长指定的长度
incrby key number
##减少指定的长度
decrby key number
127.0.0.1:6379> set fans 0
OK
127.0.0.1:6379> INCR fans ##值++
(integer) 1
127.0.0.1:6379> INCR fans
(integer) 2
127.0.0.1:6379> INCR fans
(integer) 3
127.0.0.1:6379> get fans
"3"
127.0.0.1:6379> DECR fans ##值--
(integer) 2
127.0.0.1:6379> DECR fans
(integer) 1
127.0.0.1:6379> DECR fans
5.1.3 范围操作 range
getrange key index1 index2 获取当前指定范围 如果最大长度 index2 可替为-1
5.1.4 替换操作
setrange key offset index 内容 ##offset 偏移量 指定位置开始替换
(integer) 0
127.0.0.1:6379> DECR fans
(integer) -1
127.0.0.1:6379> INCRBY stu1 100 ##值固定+N
(integer) 100
127.0.0.1:6379> INCRBY stu1 100
(integer) 200
127.0.0.1:6379> INCRBY stu1 100
(integer) 300
127.0.0.1:6379> DECRBY stu1 50 ##值固定-N
(integer) 250
127.0.0.1:6379> DECRBY stu1 50
(integer) 200
127.0.0.1:6379>

5.1.3 范围操作 range

getrange key index1 index2 获取当前指定范围 如果最大长度 index2 可替为-1
127.0.0.1:6379> set content hellojiazongnihao
OK
127.0.0.1:6379> get content
"hellojiazongnihao"
127.0.0.1:6379> STRLEN content
(integer) 17
127.0.0.1:6379> GETRANGE content 5 11
"jiazong"
127.0.0.1:6379> get content
"hellojiazongnihao"
127.0.0.1:6379> GETRANGE content 0 -1 # 获取全部字符串
"hellojiazongnihao"
127.0.0.1:6379>

5.1.4 替换操作

setrange key offset index 内容 ##offset 偏移量 指定位置开始替换
127.0.0.1:6379> GETRANGE content 0 -1
"hellojiazongnihao"
127.0.0.1:6379> SETRANGE content 5 sunzong #将sunzong覆盖jiazong
(integer) 17
127.0.0.1:6379> GETRANGE content 0 -1
"hellosunzongnihao"
127.0.0.1:6379> SETRANGE content 5 wang #将wang覆盖jiaz
(integer) 17
127.0.0.1:6379> GETRANGE content 0 -1
"hellowangongnihao"
127.0.0.1:6379>

5.1.5 判断是否存在

EXISTS t6 判断值是否存在
#set with expire #如果存在设置消失时间及信息值 -- 订单
setex key time v 既能增加过期时间还能够重新指定新的值,如果当前key不存在创建一个新的key和值并指
定过期时间
#如果一个值不想改变只想重新设定时间
127.0.0.1:6379> set message 1089
127.0.0.1:6379> expire message 300
#如果既想刷新时间又想改变值
127.0.0.1:6379> setex message 300 8888
#set if not expire #如果不存在 默认会创建一个新的,存在不操作 / 及判断存在不存在同时也能根据结果进行进一步操作
setnx key v
# 如果值存在 ,不作处理
127.0.0.1:6379> setnx message ooooooooooooooo
(integer) 0
# 如果值不存在, 执行创建
127.0.0.1:6379> setnx mess ooooooooooooooo
(integer) 1

5.1.6 批量值操作

more set 
mset k1 v1 k2 v2
mget k1 k2
127.0.0.1:6379> mset b 123 c 123 d 123
OK
127.0.0.1:6379> get c
"123"
127.0.0.1:6379> mget a b c d
1) "123"
2) "123"
3) "123"
4) "123"
127.0.0.1:6379>

5.1.7 关于对象的存储

#普通的json对象
{id:1,name:zhangsan,age:40}
#redis存储的对象
{class:[{},{}]}
{id:1,name:zhangsan,age:40}
{id:2,name:lisi,age:14}
将这个对象存储到redis中, key user 注意:字符串需要去掉引号
127.0.0.1:6379> set user {id:1,name:"zhangsan",age:40}
Invalid argument(s)
127.0.0.1:6379> set user {id:1,name:zhangsan,age:40}
OK
127.0.0.1:6379> get user
"{id:1,name:zhangsan,age:40}"
127.0.0.1:6379>
希望再存储一个李四,key 希望叫user 但是直接用会被覆盖,取值也不方便。
建议: 组合键(这个组合键目的就是将对象中的属性和值打散,通过组合不同的key到redis中读取不同的值)
方式1 : 可能后面根据ID读取某一个对象的情况
127.0.0.1:6379> set user:1 {id:1,name:zhangsan,age:40}
OK
127.0.0.1:6379> set user:2 {id:2,name:lisi,age:14}
OK
127.0.0.1:6379> keys user*
1) "user:2"
2) "user:1"
127.0.0.1:6379> get user:2
"{id:2,name:lisi,age:14}"
127.0.0.1:6379>
方式2:存在通过对象-id-属性,查询某些数据
set user:1:id 1
set user:1:name zhangsan
set user:1:age 14
set user:2:id 2
set user:2:name lisi
set user:2:age 14
# 查询所有
127.0.0.1:6379> keys user*
1) "user:2:age"
2) "user:1:age"
3) "user:1:id"
5.1.8 取值赋值操作
getset 先取值,再赋值
5.1.9 关于浮点类型的增减操作
incr decr 直接使用会报错
关键词: incrbyfloat 不支持直接+1-1操作 支持固定增减量操作
5.1.10 删除数据
del key ...
5.2 List列表类型
4) "user:2:id"
5) "user:1:name"
6) "user:2:name"
# 根据id查询
127.0.0.1:6379> keys user:1:*
1) "user:1:age"
2) "user:1:id"
3) "user:1:name"
# 根据具体条件查询
127.0.0.1:6379> get user:2:name
"lisi"
127.0.0.1:6379>

5.1.8 取值赋值操作

getset 先取值,再赋值
127.0.0.1:6379> getset student zhangsan
(nil)
127.0.0.1:6379> getset student lisi
"zhangsan"
127.0.0.1:6379> getset student wangwu
"lisi"
127.0.0.1:6379> get student
"wangwu"
127.0.0.1:6379>

5.1.9 关于浮点类型的增减操作

incr decr 直接使用会报错
127.0.0.1:6379> incr price
(error) ERR value is not an integer or out of range
关键词: incrbyfloat 不支持直接+1-1操作 支持固定增减量操作
127.0.0.1:6379> incrbyfloat price 9.9
"19.8"

5.1.10 删除数据

del key ...

127.0.0.1:6379> del ww
127.0.0.1:6379> del nn oo

5.2 List列表类型

list列表类型,特点:所有的命令操作都是使用l开始。 和链表/队列比较相似,可以通过首尾进行操作。

 工作中主要实现一些列表数据(导航、数据集List 队列消息,主要列表相关都可以存储)

5.2.1 基本赋值和取值操作


默认左侧插入值: lpush l意思 list
右侧插入值:rpush r意思 right
查询数据:lrange key start end
获取长度 llen key
127.0.0.1:6379> lpush stu zhangsan lisi
(integer) 2 #返回list长度
127.0.0.1:6379> lrange stu 0 -1 #取值
1) "lisi"
2) "zhangsan"
127.0.0.1:6379> lpush stu wangwu
(integer) 3
127.0.0.1:6379> lrange stu 0 -1
1) "wangwu"
2) "lisi"
3) "zhangsan"
127.0.0.1:6379> rpush stu zhaoliu # 结尾插入值
(integer) 4
127.0.0.1:6379> lrange stu 0 -1
1) "wangwu"
2) "lisi"
3) "zhangsan"
4) "zhaoliu"
127.0.0.1:6379> llen stu # 获取当前列表长度

5.2.2 list结构的删除数据操作

删除整个 list 列表
del key #这种是直接将整个列表都删除 del删除删除任意类型
删除 list 列表中的某一些数据
关键词: pop 弹出 抛出
语法:
lpop count 左侧弹出
# 没给count值,默认左 弹出1 返回的信息是弹出的值
127.0.0.1:6379> lpop stu
"lisi"
# count 提供值,可以弹出多个,返回值就是弹出的值得列表
127.0.0.1:6379> lpop stu 10
1) "zhangsan"
rpop count 右侧弹出
127.0.0.1:6379> rpop stu
"zhangsan"
127.0.0.1:6379> rpop stu 1
1) "lisi"
127.0.0.1:6379>
删除指定值 list remove
关键词: lrem key count value ---- 默认从左侧开始查询并删除
127.0.0.1:6379> lpush stu wangwu zhaoliu zhangsan lisi wangwu tianqi zhangsan
zhangsan
127.0.0.1:6379> lrem stu 2 zhangsan
# count正数 从左向右删除 count负数, 从右向左删除
127.0.0.1:6379> lrange stu 0 -1

5.2.3 索引相关 index

通过索引获取数据
lindex key index
127.0.0.1:6379> lindex stu 1
截取列表中一部分值
trim Java 和脚本中是去掉前后空格,本身意思 修剪、整理。 在 redis 中作用域截取部分值,截取完成只保留获取的内容。
ltrim key start end
127.0.0.1:6379> ltrim stu 1 4
列表中替换值
lset
127.0.0.1:6379> lset stu 1 zhaoliu

5.2.4 其他

在指定的一个位置前面插入值(不是索引)
在指定的一个位置后面插入值(不是索引)
linsert key before|after 原始值位置 新的值
127.0.0.1:6379> linsert stu before zhaoliu lisi
127.0.0.1:6379> linsert stu after lisi wangwu
两个列表值交换 需要两个列表, 第一个列表中的最后一个值插入到第二个列表中的第一位
rpoplpush r pop l push (右弹出左推进) 如果list1和list2为同一个,最后一个值置顶
rpoplpush list1[第一个列表] list2[第二个列表]
127.0.0.1:6379> rpoplpush stu teacher
#置顶数据
127.0.0.1:6379> rpoplpush teacherteacher

5.3 Set集合类型

特点: 无序、不能重复 所有命令 s 开头
用途:点赞,签到, like 等功能、抽奖功能

5.3.1 基本操作

通过测试:重复的值无法添加成功,并且值得顺序也不是固定的。
添加值
sadd key v........
127.0.0.1:6379> sadd book sanguoyanyi jinpingmei hongloumeng
查询值
smembers members 成员 组成
127.0.0.1:6379> smembers book
通用删除
del key 将整个集合直接删除
删除指定指定的元素 srem key value
127.0.0.1:6379> srem book jinpingmei

5.3.2 其他操作

判断当前集合中是否存在指定的值 s is member 是否是成员
语法 sismember key v
127.0.0.1:6379> sismember book jinpingmei
(integer) 1
127.0.0.1:6379> sismember book jinpingmei2
(integer) 0
查看当前集合中值个数 s card
语法:sacrd key
127.0.0.1:6379> scard book
(integer) 4
随机获取和随机删除
随机获取: srandmember [ s random member ]
语法:srandmember key count
127.0.0.1:6379> srandmember book
"jinpingmei"
127.0.0.1:6379> srandmember book 2
1) "hongloumeng"
2) "jinpingmei"
随机删除: spop
语法: spop key count
127.0.0.1:6379> spop book
"jinpingmei"
127.0.0.1:6379> spop book 10
1) "hongloumeng"
2) "sanguoyanyi"

5.3.3 特殊操作

解决中文问题
[root@sunwz ~]# redis-cli -h 127.0.0.1 -p 6379 --raw
差集 diff 差异 只返回第一个集合的差值
127.0.0.1:6379> sadd zb1 xiaozhi dasima caixukun lijiaqi
4
127.0.0.1:6379> sadd zb2 liziqi xiaozhi dasima wangdaxian xuxubaobao
5
127.0.0.1:6379> sdiff zb1 zb2
caixukun
lijiaqi
127.0.0.1:6379> sdiff zb2 zb1
wangdaxian
liziqi
xuxubaobao
127.0.0.1:6379>
交集 sinter 交集
127.0.0.1:6379> sinter zb2 zb1
dasima
xiaozhi
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值