先上官网的一个图
一.初识redis
1.1 什么是noSQL数据库
差异:
- no-structured:非结构化(没有表,约束)
- 数据之间无关系(主键/外键)
- 无固定语法(SQL)
- 无事务(ACID/base)
SQL | noSQL | |
---|---|---|
存储方式: | 磁盘 | 内存 |
扩展性: | 垂直 | 水平 |
使用场景: | 数据结构稳定;相关业务对数据安全性和一致性要求较高 | 数据结构不固定,对一致性和安全性要求不高对性能要求高 |
1.2 什么是redis
nosql数据库的一种;
- 键值类型:redis
- 文档类型:MongoDB
- 列类型:Hbase
- Craph类型:Neo4j
redis的全称是remote dictionary server,远程词典服务器,是一个基于内存的键值型的NoSQL数据库。
是一个意大利的哥们使用C语言开发的,原因就是当网站的用户量大,并发量高的时候,他就希望有这样的一个库,吞吐能力很强,并发能力很高。
性能极高 – Redis能读的速度是110,000次/s,写的速度是81,000次/s 。
特点:
- 键值类型,value支持多种不同的数据结构,功能丰富;
- 单线程,每个命令都具备原子性;
- 低延迟,速度快(基于内存,IO多路复用,良好的编码);
- 支持数据的持久化(定期);
- 支持主从集群,分片集群;
- 支持多语言客户端。
1.3 安装redis
1.3.1 win版安装
下载地址: https://github.com/tporadowski/redis/releases。
找到64位的zip;
解压, 改名为redis
cd到该目录下
然后敲以下的命令
redis-server.exe redis.windows.conf
以配置文件的配置启动服务端.
再在另一个窗口敲以下命令
redis-cli.exe -h 127.0.0.1 -p 6379
开启客户端登录redis
最后做一下测试
敲以下的命令
set myKey abc
设置键值对
get myKey
取出键值对
1.3.2 linux版安装
事实上,redis的官方并没有编写win版的redis服务器,而是只有Linux版本的。网上的win版的redis是微软官方自己编译的。
所以,这里我们选择使用Linux系统(centOS7)来部署redis。
下载地址: http://redis.io/download
第一步:
需要gcc依赖;
yum install -y gcc tcl
将在这个位置解压
cd /usr/local/src/
解压
tar -zxvf redis-6.2.6.tar.gz
进入安装包目录
cd redis-6.2.6
编译并安装
make && make install
如果没有出错,就安装成功了.并配置好了环境变量.
默认的安装路径是在/usr/local/bin目录下
cd /usr/local/bin/
查看
ls -l
任意目录下
redis-server(tab有提示,证明已经加入了)
不出意外就启动成功
备份配置文件
cp redis.conf redis.conf.bck
1.3.3 redis的一些配置
修改redis.conf文件
监听的地址, 默认是127.0.0.1, 修改为0.0.0.0就可以在任意的ip访问这个redis, 注意生产环境不能是这个.
bind 0.0.0.0
守护进程, 修改为yes之后就可以在后台运行
daemonize tes
可以使用这个命令查看是否运行起来了
ps -ef | grep redis
使用
kill -9 进程号
杀死进程.
密码, 设置后访问的redis必须输入密码
requirepass 123456
监听的端口
port 6379
工作目录, 默认就是当前目录, 也就是运行redis-server时的命令,日志,持久化等文件会保存在这个目录
dir .
日志文件, 默认为空, 不记录日志, 可以指定日志文件名
logfile "redis.log"
这两个结合就是日志文件的地方
数据库的数量, 默认是有16个库, 编号为0~15, 这里先设置为一个
databases 1
设置redis能够使用的最大的内存是多少
maxmemory 512mb
二.redis的常见的命令
2.1 redis的常见客户端
包括
- 命令行客户端 (这个是和redis一并安装的)
- 图形化界面客户端(github上的大神编写的)
- 编程客户端
2.2 使用客户端登录redis
自带的命令客户端:
redis-cli [options] [commonds]
其中常见的options有
-h ip地址
指定要连接的redis节点的ip地址,默认是127.0.0.1
-p 端口
指定要连接的redis节点的端口,默认是6379
-a 密码
指定redis的访问密码
其中commonds就是redis的操作命令, 例如
ping
与redis服务器做心跳测试, 服务器正常就会返回pong
不指定commods时, 会进入redis-cli的交互控制台.
2.3 redis的常用数据结构和命令
2.3.1 redis的数据结构介绍
redis是一个键值型的数据库, 一般key是String类型, 但是value就是类型多种了.
常见的呢就是以下这五种
String: hello world
Hash: {name: “jack”, age: “22”}
List: [A -> B -> C ->D]
Set: {A , B, C}
SortedSet: {A: 1, B: 2, C: 3}
这以上的五种叫做基本类型, 事实上value的数据类型还有很多种, 后面再单独讲解, 现在先从这五个入手, 学会两个问题, 一个是这么多种数据结构, 各自是怎么用的问题, 还有一个就是什么时候, 使用什么类型的问题.
2.3.2 redis的通用命令
help @[group]
查看对应的数据结构相关的命令
help @generic
查看所有通用命令
help 命令
查看一个命令的具体信息
keys *
查看该库下的所有key
select 库索引
换库
keys a*
查看a开头的key
事实上, 生产环境下不建议使用这个keys命令, 因为当库中的命令很多时, 会花费很大的时间, 又因为redis的命令都是单线程的, 所以就相当于此时redis的被阻塞的状态.
del key
删除一个指定的key
这个命令可以批量删除key, 用空格隔开就行.
返回值是删除的key的数量, 也就是说指定的key不存在时, del就不会生效.
mset
就是批量插入
exists key
判断一个key是否存在
expire key seconds
给一个key设置有效期, 有效期到期时该key会被自动删除
ttl key
查看一个key的存活时间, -1是永久存活, -2是不存在或者死了.
2.3.3 常用的五种数据结构
String类型
(1)底层原理
在redis中不像在编程中或者MySQL中,String类型的value可以存放的可不仅仅只是字符串,而是int和float都是String,并且也可以完成自增和自减的操作。
底层事实上都是字节数组。
但是,细节就在于字符串数据编码成字节码,存进字节数组,而数字转成二进制数据存进字节数组,这样一个字节就可以存放一个很大的数字了。目的就是为了节省空间。其实就是编码的方式不同,另外String类型的最大空间只有512mb。
(2)常见命令
set:添加或者修改一个String类型的键值对,不存在key就添加,存在就修改。
get:很具key获取value
mset:批量的添加
mget:批量的获取
incr:让一个int的key自增1
incrby:指定增步长
把值改成负数就是减
incrbyfloat:指定增
浮点数没有默认增长,一定要指定步长
setnx:添加一个String类型的键值对,前提是这个key不存在,否词不添加。
事实上是一个组合命令,先是set再是nx,最后在加nx也是一样的。
setex:在设置时就指定存活时间。
就可以不用使用通用命令再设置了。
事实上,value可以存放一个json格式的字符串,配合key的层级写法,也可以实现像表一样的去元组。
但是有一个弊端,就是value其实是一个String,就算序列化成了json格式,依然是一个整体,无法对单独某一个字段做操作。
Hash类型
(1)底层原理
也叫散列,其value就是无序的字典,类似于Java中的HashMap集合。
说白了就是value本身又是一个键值对结构。
此时,突然发现以上说的String类型的弊端被解决了(一部分)。
也就是,value又被分为field,和value两个部分。
(2)常见命令
事实上就是基于String的命令前面加上一个H
hset
hget
hmset
hmget
hgetall:获取一个key的所有field和value
hkeys:获取一个key的所有field
hvals:获取一个key中的所有value
hincrby:指定到具体的一个field上,并指定步长
hsetnx:判断到field存在吗,不存在才添加。
List类型
(1)原理
redis的list类型就类似Java中的linkedlist,可以看成一个双向链表,既可以支持正向检索,也可以反向检索。
特征也与linkedlist类似
有序
元素可以重复(评论)
插入和删除快
查询速度一般
说白了就是value不止一个String类型
(2)命令
lpush:向列表左侧插入一个或者多个元素。
lpop:移除并返回列表左侧的第一个元素,没有则返回nil
rpush:向列表右侧插入一个或者多个元素
rpop:移除并返回列表右侧的第一个元素,没有则返回nil
lrange key start end:返回一个段角标范围的所有元素。
blpop和brpop:和lpop和rpop类似,只不过在没有元素时等待指定时间,而不是直接返回nil(阻塞式获取)
(3)模拟
如何用一个list结构模拟一个栈
- 同一个口进同一个口出
模拟一个队列
- 一边进一边出
模拟一个阻塞队列
- 不在同一边
- 并且使用blpop和brpop
Set类型
(1)底层
类似Java的hashset。只实现了key的hashMap,
无序
不可重复
查找快
支持交集,并集,差集等功能(好友列表,共同好友,关注列表)
说白了,这个和list应该一起来理解。
又是单列,就是都是可以value中存放不止一个String
底层的数据结构不同,还有就是有序无序不同,还有就是查询和插删的效率不同,重复与否不同,用处自然也就不同。
(2)命令
sadd:
srem:
scard:返回指定的key的元素的个数
sismember key member:判断一个元素是否就在set中。
smembers:获取set中指定key的所有元素。
sinter key1 key2 … :求交集
sdiff key1 key2 …:求差集
sunion key1 key2 …:求并集
SortedSet类型
(1)原理
redis的sortedset是一个可排序的set集合,与Java中的treeset有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都是带有score属性,可以基于score属性对元素进行排序,底层的实现是一个跳表(skipList)加hash表,
可排序
元素不重复
查询速度快
因为SortedSet的可排序性(做排行榜)
(2)命令
zadd key score1 member1 score2 member2 …
:如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
zscore key member
:返回指定成员的分数。
zcard key
:获取集合中的成员数量
zrem key member1 member2 …
:删除元素
zrange key start end [withscores]
:获取集合中脚标为start到end的成员,[withscores]参数表明返回的成员包含其分数。
zrevrange key start stop [withscores]
:照元素分数从大到小的顺序返回索引从start到stop之间的所有元素。
zremrangebyscore key min max
:按照分数范围删除元素
zcount key min max
:获取分数在[min max]之间的成员个数
zrank key member
:返回成员在集合中的排名。索引(从大到小)
zdiff、zinter、zunion
:求差集,交集,并集
三. redis的Java客户端
jedis:以redis的命令作为方法的名称,学习成本低,简单实用,但是jedis实例是线程不安全的,多线程环境下要基于连接池来使用。(每一个线程创建独立的redis连接)
lettuce:是基于netty网络框架实现的,支持同步、异步、响应式编程方式,是线程安全的,支持redis的哨兵模式,集群模式和管道模式。(S
pring的默认使用的redis客户端)
redision:基于redis实现的分布式、可伸缩的Java数据结构集合,说白了是基于redis的一套工具。(包含map、queue、lock、semaphore、atomiclog等强大的功能)
jedis客户端
SpringDataRedis客户端