一、初识Redis
0.目标
- 认识NoSQL
- 认识Redis
- 安装Redis
1.认识NoSQL
我们在之前已经学过了SQL类型的数据库,如MySQL,而NoSQL型的数据库虽也是用来存储数据的,但是他与SQL型数据库有很大的不同,具体体现在以下方面
SQL | NoSQL | |
---|---|---|
数据结构 | 结构化 | 非结构化 |
数据关联 | 关联的 | 非关联 |
查询方式 | SQL | 不固定 |
事务特征 | ACID | BASE |
储存方式 | 磁盘 | 内存 |
扩展性 | 垂直 | 水平 |
使用场景 | 1)数据结构固定;2)相关业务对数据安全性、一致性要求较高 | 1)数据结构不固定;2)对一致性、安全性要求不高;3)对性能要求高 |
- 数据结构
- SQL
- 结构化
- 即由字段与约束构成的表组成
- 结构化
- NoSQL
- 非结构化
- 结构不固定,其储存形式主要有如下四种
- 键值形式(Redis)
- 文档类型(MongoDB)
- 列表类型(HBase)
- 图类型(Neo4j)
- 非结构化
- SQL
- 数据关联
- SQL
- 关联的
- 即表之间可以通过主键外键来相互关联,系统会对关系进行处理
- 关联的
- NoSQL
- 非关联的
- 即系统不处理关系,数据之间的关联由使用者自己使用逻辑来处理
- 非关联的
- SQL
- 查询方式
- SQL
- 统一用SQL查询
- NSQL
- 非SQL,不统一,不同数据库有不同的查询方式
- SQL
- 事务特征
- SQL
- ACID
- NoSQL
- BASE
- SQL
- 存储方式
- SQL
- 磁盘
- 储存量大,但是速度较慢
- 磁盘
- NoSQL
- 内存
- 储存量小,但是速度非常快
- 内存
- SQL
- 扩展性
- 垂直
- 即性能取决于数据库所在的主机
- 水平
- 可以通过多台主机联系起来提高性能
- 垂直
- 使用场景
- SQL
- 数据结构固定
- 相关业务对数据安全性、一致性要求较高
- NoSQL
- 数据结构不固定
- 对一致性、安全性要求不高
- 对性能要求高
- SQL
2.认识Redis
2.1 简介
Redis全称Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库。
2.2 特征
- 键值(key-value)型,value支持多种不同的数据结构,功能丰富
- 单线程,每个命令具备原子性,不会相互影响
- 低延迟,高速度(基于内存、IO多路复用、良好的编码)
- 支持数据持久化(会定期将内存的数据持久化到磁盘中)
- 支持主从集群、分片集群
- 支持多语言客户端
2.3 安装Redis
2.3.1 单机安装Redis
2.3.1.1 安装Redis依赖
Redis是基于c语言的,故首先需要安装Redis所需要的gcc依赖
yum install -y gcc tcl
2.3.1.2 上传Redis安装包并解压安装
安装包下载地址:Index of /releases/ (redis.io)
上传到服务器后,使用如下命令解压
tar -zxvf redis-7.4.0.tar.gz
解压后使用cd进入文件夹
cd redis-7.4.0
再进行编译与安装
make install
安装流程参考:
史上最详细centos 7环境下安装并启动redis_centos7 redis 启动-CSDN博客
2.3.2 启动Redis
2.3.2.1 默认启动方式
安装完成后,我们可以进入到安装目录下的src文件夹,在终端输入./redis-server
启动Redis,启动成功后会出现如下界面
要想在任意处使用该命令启动服务,我们需要将命令添加到环境变量中去
步骤如下:
-
进入上文提到的src文件夹
-
在文件夹内输入命令
pwd
-
复制输出的路径
-
编辑
/etc/profile
文件- 输入命令
vim /etc/profile
即可进入编辑该文件
- 输入命令
-
在文件末尾添加如下内容
-
export PATH=$PATH:你复制的路径 # $PATH :表示将此路径追加到系统的环境变量
-
-
运行命令
source /etc/profile
立即启用修改
环境变量添加完成后即可在任意位置使用redis-server
启动redis服务了
但是,此种默认启动方法有不小的缺陷,其中最重要的是他会占用该窗口,导致我们无法使用该窗口进行其他的操作,故一般不使用这种方法启动
2.3.2.2 指定配置启动
如果想要Redis以后台方式启动,则必须要修改Redis的配置文件,配置文件在我们安装Redis的目录下,名字叫redis.conf
在修改该文件前,我们先对其进行一次备份
cp redis.conf redis.conf.bak
接着,使用vim打开文件并修改,主要修改项如下:
#允许访问的地址,默认为127.0.0.1,使得数据只能在本地访问。修改为0.0.0.0可以使得任意ip都可以访问,编写测试时可以这样设置,但是部署时为了安全性考虑建议使用默认值
bind 0.0.0.0
#守护进程,修改为yes后可以在后台运行
daemonize yes
#密码,设置后访问Redis必须输入密码
requirepass 123321
其他常见配置
#监听端口,默认6379
port 6379
#工作目录,默认为当前目录,即启动Redis-server时的目录,日志,持久化文件都会存储到这个目录下
dir .
#数据库数量,设置为n,即有n个库,默认为16个,编号为0-15
databases 1
#设置Redis能够使用的最大的内存
maxmemory 512mb
#日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
启动时,在命令后跟上配置文件即可使用配置文件启动,即redis-server redis.conf
可以看到,在我们执行启动命令后,并没有任何输出,这是因为程序已经进入后台执行,故不会输出
我们可以通过命令
ps -ef |grep redis
查看Redis服务,并使用kill来杀掉进程
2.3.3 Redis客户端
安装并启动了Redis服务后,我们就可以通过操作Redis来实现数据的增删改查了。这里需要使用Redis的客户端,包括:
- 命令行客户端
- 图形化桌面客户端
- 编程客户端
2.3.3.1 命令行客户端
Redis安装时自带了命令行客户端:redis-cli
其启动命令如下:
redis-cli [option] [commonds]
注:若我们前面成功添加了环境变量,则该命令在何处都能使用,否则得去安装目录使用
常见的option
-h 127.0.0.1
:指定要连接的Redis节点的ip地址,默认为127.0.0.1-p 6379
:指定要连接的Redis节点的端口,默认为6379-a 123321
:访问密码
commonds为Redis的操作指令,可以在此输入,也可以连接Redis后输入
如:
ping
:与服务器做心跳测试,服务端正常会返回pong
其中,若服务器设置了密码,则只有输入过密码的用户才可操作服务器,输入密码有两种方式:
- 在启动客户端时携带密码
- 如:
redis-cli -a 123321
- 如:
- 在连接到服务器后输入
AUTH [usr] password
- 如:
AUTH 123321
- 如:
在获取服务器操作权限后,才可以发送指令,例:
2.3.3.2 图形化客户端
官方并未提供图形化客户端,但是github上有大佬自己编写了windows下的图形化客户端
发行版 · lework/RedisDesktopManager-Windows (github.com)
安装完成后连接服务器即可
注:ip地址可以在linux中使用命令ip addr
进行查询,ens开头的那段中含有我们所要的ip地址
如果还是无法连接可以尝试关闭linux防火墙(不建议),命令:systemctl stop firewalld
或者可以对我们访问的端口进行放行:
firewall-cmd --zone=public --add-port=6379/tcp --permanent
#--permanent表示该放行规则将会被永久保存
firewall-cmd --reload
#修改完成后使用此命令来重启防火墙,使得新规则生效
注:安装时报错看这儿
安装zlib
更新python
CentOS 7升级Python到最新版3.9.1_centos更新python3.9版本-CSDN博客
网络错误->yum换源
【Linux】CentOS更换国内阿里云yum源(超详细)_centos更换yum源-CSDN博客
文件传输错误->启用共享文件夹
电脑主机与VMware虚拟机共享文件详细教程_vmware 打开共享文件夹-CSDN博客
编译错误->安装gcc,TCL
安装gcc:
yum install gcc
【详细教程】linux中安装tcl_how to build and install tcllib-CSDN博客
设置中文输入法
CentOS系统设置中文输入法,并切换输入法_centos中文输入法切换-CSDN博客
二、Redis常见命令
0.目录
- Redis数据结构介绍
- Redis通用命令
- String类型
- Hash类型
- List类型
- Set类型
- SortedSet类型
1.Redis数据结构介绍
Redis是一个key-value的数据库,key一般是String类型,但是value的类型多种多样:
类型 | 所属 | 例 |
---|---|---|
String | 基本类型 | hello world |
Hash | 基本类型 | {name:“sakura”,age:20} |
List | 基本类型 | [A->B->C] |
Set | 基本类型 | {A,B,C} |
SortedSet | 基本类型 | {A:1,B:2,C:3} |
GEO | 特殊类型 | {A:(120.3,30.5)} |
BitMap | 特殊类型 | 0110110101110101011 |
HyperLog | 特殊类型 | 0110110101110101011 |
在Redis中,我们可以通过help
命令来查看指定命令作用,如:
2.Redis通用命令
通用命令是对任何的数据类型都可以适用的命令,常见的通用命令有:
keys
:查看符合模版的所有key- 可以使用通配符*和?
- 该查询为模糊查询,数据量大时速度慢,且由于Redis是单线程,故不建议在生产环境设备上适应,或至少不应该在主机上使用,可以尝试在节点上使用
- 例
keys *
查询所有的key
del
:删除一个指定的key- 例:
del name
删除key name
- 例:
exists
:判断一个key是否存在- 返回1表示存在,0为不存在
- 例:
exists name
判断key name是否存在
expire
:给一个key设置有效期,有效期到期该可以会被删除,单位为秒- 例:
expire name 20
设置key name有效期为20s
- 例:
ttl
:查看key的剩余寿命- 返回值为大于零的整数即为剩余寿命,-2为不存在,-1为永久有效
- 例:
ttl name
查看key name 的剩余寿命
例:
0.0.0.0:6379> set name Sakura
OK
0.0.0.0:6379> set age 20
OK
0.0.0.0:6379> del age
(integer) 1
0.0.0.0:6379> keys *
1) "name"
0.0.0.0:6379> exists name
(integer) 1
0.0.0.0:6379> exists age
(integer) 0
0.0.0.0:6379> ttl name
(integer) -1
0.0.0.0:6379> expire name 20
(integer) 1
0.0.0.0:6379> ttl name
(integer) 16
0.0.0.0:6379> ttl name
(integer) 9
0.0.0.0:6379> ttl name
(integer) -2
0.0.0.0:6379> keys *
(empty array)
3.String类型
3.1 概述
String类型,也就是字符串类型,是Redis中最简单的储存类型
其value是字符串,不过根据字符串的格式不同,又可以分为三类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自减操作
不管哪种格式,底层都是字节数组形式存储,只不过编码方式不同,字符串类型的最大储存空间不能超过512m
例:
key | value |
---|---|
name | Sakura |
age | 18 |
score | 99.5 |
3.2 String常见命令
set
:添加或修改已经存在的一个String类型的键值对- 如:
set name sakura
- 如:
get
:根据key获取String类型的value- 如:
get name
- 如:
mset
:批量添加或修改多个String类型的value(k v格式)- 如:
mset name sakura age 20 soccer 95.1
- 如:
mget
:根据多个key获取多个String类型的value- 如:
mget name age
- 如:
incr
:让一个整型的key自增1- 如:
incr age
- 如:
incrby
:让一个整型的key自增并指定步长- 如:
incrby age 10
- 如:
incrbyfloat
:让一个浮点型的数字自增并指定步长,该处步长必须指定- 如:
incrbyfloat soccer 10
- 如:
setnx
:尝试添加一个String类型键值对,如果不存在则添加,存在则不添加- 该命令还可以拆分输入:
set k v nx
,但是两种方式返回不同前一种方式返回0或1,后一种方式返回nil或ok - 如:
setnx name Jack
与set name Jack nx
作用等价
- 该命令还可以拆分输入:
setex
:添加一个String类型的键值对,并指定有效期- 该命令也可以如上一条命令一样进行拆分
- 如:
setex name 10 sakura
与set name sakura ex 10
作用等价
4.Hash类型
4.1 概述
Hash类型也叫做散列,其value为一个无序的字典,类似于python中的字典。
相较于利用String结构将对象化为JSON字符串储存,Hash结构直接将对象中的每个字段用类似于python字典的形式独立储存,可以对单个字段进行修改,使得处理数据更加便利。
对比:
String结构
Hash结构
4.2 Hash类型常见命令
hset key field value
:添加或者修改hash类型key的field所对应的valuehget key field
:获取一个hash类型key的field的valuehmset key field1 value1 field2 value2 ...
:批量添加或设置一个key的filed与valuehmget key f1 v1 f2 v2 ...
:批量获取一个key的filed与valuehgetall key
:获取一个key的全部的field和valuehkeys key
:获取一个key的全部fieldhvals key
:获取一个key的全部valuehincrby key field [step]
:让一个key的field的value自增并指定步长hsetnx key f v
:对指定key添加field与value,若该field存在则不添加
5.List类型
5.1 概述
Redis里的list类型为一个双向的链表,可以对头尾进行操作,其有如下特征
- 有序
- 元素可重复
- 插入和删除快
- 查询速度较一般
5.2 List类型常见命令
lpush key element
:向表的左侧插入一个或多个元素- 插入多个元素时,按照从左向右的顺序对每个元素进行插入
lpop key
:弹出列表左侧第一个元素,没有则返回nilrpush key element
:向列表的右侧插入一个或多个元素rpop key
:弹出列表右侧第一个元素lrange key star end
:返回角标star到end范围内的所有元素blpop|brpop time
:与lpop和rpop类似,但是在没有元素时等待指定时间,而不是直接返回nil
6.Set类型
6.1 概述
Set类型即为集合,其value是一个集合,具有无序,元素不重复的特性
6.2 Set类型常见命令
sadd key member
:向set中添加一个或多个元素srem key member
:移出set中的指定元素scard key
:返回set中元素的个数sismember key member
:判断一个元素是否在set中smembers key
:获取set中所有的元素sinter key1 key2
:求set1与set2的交集sdiff key1 key2
:求set1与set2的差集sunion key1 key2
:求key1与key2的并集
7.SortedSet类型
7.1 概述
SortedSet是一个可排序的集合,其元素存储虽然还是无序的,但是由于其每个value都有一个score,故可以依据score对value进行排序,使得查询速度加快
7.2 SortedSet类型常见命令
zadd key score member
:添加一个或多个值到SortedSet中,若值已经存在,则更新其scorezrem key member
:删除SortedSet中一个指定元素zscore key member
:获取SortedSet中指定元素的scorezrank key member
:获取SortedSet中指定元素的排名zcard key
:获取SortedSet中的元素个数zcount key min max
:统计SortedSet中,score在min到max范围内的元素的个数zincrby key increment member
:让SortedSet中指定元素以步长为increment进行自增zrange key min max
:按照score排序后,获取排名为min到max范围内的元素zrangebyscore key min max
:按照score排序后,获取指定score范围内的元素zdiff、zinter、zunion
:求差集、并集、交集
拓:Key的结构
由于Redis是依靠键值对来存储数据的,并没有类似mysql中的表的格式,那么我们如何区分不同类型的key呢?
在Redis中,key允许有多个单词形成层级结构,多个单词之间可以使用 : 来隔开,这样数据库就会按照层级来储存key,其格式如下:
项目名:业务名:类型:id
如:
假如我们现在有一个项目名叫project
,里面有两种类型数据user
和product
,我们可以这样定义key:
key | value |
---|---|
project:user:1 | “{‘id’:1,'name:‘sakura’,‘age’:21}” |
project:user:2 | “{‘id’:2,'name:‘Jack’,‘age’:20}” |
project:product:1 | “{‘id’:1,‘name’:‘Gun’,‘price’:114514}” |
project:product:2 | “{‘id’:2,‘name’:‘Gun2’,‘price’:11111}” |
在cli中我们可能看不出来什么,但是当我们打开图形客户端,就可以看到数据形成了明显的层级结构