1. 架构的演变
1.1 单体/库架构
90
年代开始,当时主流的技术是
JSP/HTML+Servlet+JDBC
,那个时候网站上基本的网站访问量都不会太大, 所以单机数据库就已经完全胜任。那个时代互联网刚刚发展! select * select
列名
where
条件要精准
架构的瓶颈:
1.数据量太大怎么办?
2.数据访问量太大怎么办?
--
(读写混合)
3.当数据库单表数据超出千万级别,就必须需要创建索引,内存放不下怎么办?
1.2
缓存
+
读写分离
+
垂直拆分
![](https://i-blog.csdnimg.cn/blog_migrate/5f2f6ba4dd5e2f2670b733e582ce5ce4.png)
单纯的实现了读写分离确实也解决了服务器压力,但是不足以胜任日益增长的访问量,然后我们将矛头指向了架构优化,如何优化
瓶颈:
用户量和数据量越来越大,即使我们通过读写分离和分库分表也不足以支撑的时候,单表数据量已经爆炸了。
1.3
分库分表
+
水平拆分
(MySQL
集群
)
![](https://i-blog.csdnimg.cn/blog_migrate/216cb4b003415ac407dae713ae70d067.png)
瓶颈:
近
10
年,是历史上科技发展最迅速的
10
年,我们的数据从简单的文字、图片也已经转变为各式各样的数据类型,那么传统的关系型数据库MySQL
已经不满足我们现在发展的需求。图片、热点数据、大篇幅文章、定位信息等各式各样的数据扑面而来!,那么就需要我们挨个解决,
如果有一个数据库能帮助我们分担这种特殊的数据,那么关系型数据库(
MySQL
、
Oracle
)的压力也就会变小了。
同时数据的存储也从
IO 1+1
变成了
IO 1+N
1.4
当下互联网公司架构
![](https://i-blog.csdnimg.cn/blog_migrate/62504a00bef2c812a94de7d182d0b9e7.png)
那么我们对架构的分析,大家也了解到,目前互联网项目对于各式各样的数据我们
MySQL这种关系型数据库存储数据就显得特别疲惫,那么这个时候
NoSQL(非关系型)数据库就随之而来。
2. 关于NoSQL
NoSQL ----
错误翻译
没有
SQL
正确翻译:
Not Only SQL
(不仅仅是
SQL
) 泛指我们非关系数据库,主要适用于
web2.0
时代。
![](https://i-blog.csdnimg.cn/blog_migrate/99d263ffc8b13d0229559f7379b909fb.png)
2.1 区别
关系型:
表
-
行
-
列
![](https://i-blog.csdnimg.cn/blog_migrate/96af0b6699f353bb77c724ec4bcbaaee.png)
非关系型
典型的就是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
淘宝架构分析
![](https://i-blog.csdnimg.cn/blog_migrate/8dde5f052c066e31a1b9413be4392baf.png)
商品基本信息 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下
![](https://i-blog.csdnimg.cn/blog_migrate/f3ed1f2b9cfa519a84a78ab21fe00643.png)
解压文件夹:
解压后进入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
环境服务所在的位置
![](https://i-blog.csdnimg.cn/blog_migrate/8d49730b7bdca31958ab130d1777ab22.png)
启动测试
redis-server
redis-server redis-config #后面是配置文件路径
2.2.3 配置redis
安装
vim
编辑器
yum -y install vim*
备份文件
在
redis
配置文件的同级目录创建一个文件夹并且
cp
一个
redis.conf
文件到新的文件夹,
以后我们使用这个
cp
的文件进行操作,原生原件不变动。
![](https://i-blog.csdnimg.cn/blog_migrate/03041db5a717500fdee81baa693ae58b.png)
修改后台启动
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
![](https://i-blog.csdnimg.cn/blog_migrate/c93cb36e8737776cf68479eb7b0173b8.png)
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