大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis.
此处选择的Linux版本为CentOS 7.
Redis的官方网站地址:https://redis.io/
Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖:
yum install -y gcc tcl
然后用Xftp将课前资料提供的Redis安装包上传到虚拟机的任意目录:
usr/local/src目录放的是压缩包
例如,我放到了/usr/local/src 目录:
cd /usr/local/src
解压缩:
tar -zxvf redis-6.2.6.tar.gz
解压后:
进入redis目录:
cd redis-6.2.6
运行编译命令:
make && make install
如果没有出错,应该就安装成功了。
redis默认的安装路径是在 /usr/local/bin
目录下:
该目录以及默认配置到环境变量,因此可以在任意目录下运行这些命令。其中:
redis的启动方式有很多种,例如:
安装完成后,在任意目录输入redis-server命令即可启动Redis:
redis-server
这种启动属于前台启动
,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C
则Redis停止。不推荐使用。
如果要让Redis以后台
方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/usr/local/src/redis-6.2.6
),名字叫redis.conf
我们先将这个配置文件备份一份:
cp redis.conf redis.conf.bck
这件就可以放心的修改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 123321
Redis的其它常见配置:
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
启动Redis:
# 进入redis安装目录
cd /usr/local/src/redis-6.2.6
# 启动
redis-server redis.conf
停止服务:
# 利用redis-cli来执行 shutdown 命令,即可停止 Redis 服务,
# 因为之前配置了密码,因此需要通过 -u 来指定密码
redis-cli -u 123321 shutdown
我们也可以通过配置来实现开机自启。
首先,新建一个系统服务文件:
vi /etc/systemd/system/redis.service
内容如下:
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
这个地方注意可能会出现这个错误
Failed to execute operation: Bad message
原因就是vim /etc/systemd/system/redis.service创建的文件有问题,复制内容时,文件中的[Unit]变成了t]。这是因为没有在编辑模式下复制,导致直到遇到[Unit]中的字母i才进入编辑模式,所以只有t],因此复制粘贴前,先按字母i进入编辑模式再粘贴。
然后重载系统服务:
systemctl daemon-reload
现在,我们可以用下面这组命令来操作redis了:
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
执行下面的命令,可以让redis开机自启:
systemctl enable redis
安装完成Redis,我们就可以操作Redis,实现数据的CRUD了。这需要用到Redis客户端,包括:
Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:
redis-cli [options] [commonds]
redis-cli [option] 前面几个是用来连上redis
其中常见的options有:
-h 127.0.0.1
:指定要连接的redis节点的IP地址,默认是127.0.0.1-p 6379
:指定要连接的redis节点的端口,默认是6379-a 123321
:指定redis的访问密码其中的commonds就是Redis的操作命令,例如:
ping
:与redis服务端做心跳测试,服务端正常会返回pong
不指定commond时,会进入redis-cli
的交互控制台:
测试
注意在连接redis客户端命令行的时候,必须要先开启redis
你可以先查看redis是否开启
systemctl status redis
如果没有开启,则开启redis
systemctl start redis
如果开启了继续执行下面的命令
连接本机的redis
redis-cli -h 虚拟机的ip地址 -p redis的端口号
redis-cli -h 192.168.186.128 -p 6379
用ping命令来测试网络是否连接
ping的原理:
向指定的网络地址发送一定长度的数据包,按照约定,若指定网络地址存在的话,会返回同样大小的数据包,当然,若在特定时间内没有返回,就是“超时”,会被认为指定的网络地址不存在。
出现错误
(error) NOAUTH Authentication required.
解释:没有权限。
也就是说我们需要输入redis需要的密码
回到中端(crtl+c),修改以上的连接redis命令行客户端的命令
redis-cli -h 虚拟机ip地址-p redis端口号 -a 在redis.conf文件中设置的requirepass的值
再重新ping
连接成功。
这里有个警告,说是用-a来指定密码太危险了
那么我们在连接的时候,可以先不指定密码,可以通过 AUTH 来指定用户名和密码,没有用户名就只填密码。
在redis内进行存取操作
GitHub上的大神编写了Redis的图形化桌面客户端,地址:https://github.com/uglide/RedisDesktopManager
不过该仓库提供的是RedisDesktopManager的源码,并未提供windows安装包。
在下面这个仓库可以找到安装包:https://github.com/lework/RedisDesktopManager-Windows/releases
在课前资料中可以找到Redis的图形化桌面客户端:
解压缩后,运行安装程序即可安装:
此处略。
安装完成后,在安装目录下找到rdm.exe文件:
双击即可运行:
点击左上角的连接到Redis服务器
按钮:
在弹出的窗口中填写Redis服务信息:
点击确定后,在左侧菜单会出现这个链接:
点击即可建立连接了:
这里可能会出现连接时长超时,连接失败的问题
Connection: Disconnect on error: Connection timeout
我们需要关闭防火墙
解决方案:在linux中使用代码关闭了防火墙。
sudo systemctl stop firewalld.service #停止firewall
sudo systemctl disable firewalld.service #禁止firewall开机启动
Redis默认有16个仓库,编号从0至15. 通过配置文件可以设置仓库数量,但是不超过16,并且不能自定义仓库名称。
如果是基于redis-cli连接Redis服务,可以通过select命令来选择数据库:
# 选择 0号库
select 0
1、首先查看redis-server是否正在运行/启动:
ps aux | grep redis
2、关闭进程:
kill -9 进程号
3、删除redis相应的文件夹
sudo rm -rf /home/xl/redis
Hash表,List可重复有序的,set不可重复无序的。
下面三种是基于基本类型的基础上进行了特殊的处理用来实现特殊功能。
5种基本类型,3中复杂类型。
help
redis为了方便我们学习,将操作不同数据类型的命令也做了分组。这个不需要死记硬背,只需要参考文档学习。
只要会帮助文档help就可以知道怎么用命令。
使用,查询所有的key值
模糊查询
注意,这种模糊查询是不友好的
,会给服务器造程很大负担。因为redis是单线程的,如果用户数据量过大,需要查询很多,查询时间很多。那么此时是无法执行其他命令的,
exist key值
expire key值 有效期
ttl key值
数值类型在做编码的时候是不同的,将数字转为二进制作为字节进行存储,一个字节可以表示一个很大的数字,可以节省空间。字符串只能将字符转为对应的字节码,然后存储,相对来说,空间较大。
set key值 value值
set 用来添加一个String类型的键值对或者修改key的value
语法
mset key1 value1 key2 value2 key3 value3
mget key1 key2 key3
语法
incr key
增长指定的数字。
incrby key 整数
添加一个String类型的键值对,如果不存在,执行,存在不执行。
已知key值为age的键值对
添加一个String类型的键值对,并且指定有效期
set key值 有效期 value值
面对复杂的业务,当商品和用户的属性冲突的时候,我们如何解决呢?
value值是json字符串的形式
hash表会将value值进一步划分,将对象中的每一个字段独立存储。当想要修改某个字段的值的时候,对其他字段没有任何影响。
hset key值 field1 value1 field2 value2
hget key值 field //hget只能获取一个filed的value值
批量添加或者获取多个hash类型key的field的value值
hmset key值 filed1 value1 filed2 value2
hmget key值 fied1 filed2 filed3
hmset 可以设置多个filed-value hset也是可以
hmget可以获取key值中的多个fied,这个hget不可以
获取一个hash类型的key中的所有的field和value
hgeall key值
获取一个hash类型的key中所有的field
hkeys key值
获取一个hash类型的key中所有的value值
hvals key值
让一个hash类型的key的字段值自增并指定步长
hincrby key值 field 步长
添加一个hash类型的key的field值,前提是这个field不存在,否咋不执行。
hsetnx key值 field value
从左边插入
LPUSH key值 value1 value2 value3
先插1,再插2,最后插3,客户端Redis最终显示如下
从右边插入
RPUSH key值 value1 value2 value3
从左边弹出,取出元素
LPOP key值 弹出元素的个数
RPOP key值 弹出元素的个数
lrange key 坐标1 坐标2
在没有元素时阻塞
BLPOP key值 超时时间
弹出的是一个元素,如果这个list集合内部没有元素,那么会阻塞一直到超时时间停止阻塞。如果这个元素存在则弹出。
批量
sadd key 元素值(可多个)
向set集合中添加元素
可以批量添加元素
set集合中的元素是不可重复的,因此成功插入了两个元素0,9
set集合中已经有0,此时加入0是无效的
向集合中删除元素
srm key 元素值(可多个)
查看集合中的所有元素
smembers key
sismember key value
ZADD key score member
可以查询一些测试数据,这个功能可以腿酸地理位置的信息,两地之间的距离,方圆几里的人
他只有个6个命令。
因为这个特殊的数据类型和地理相关,需要用到地理的经纬度,可以推荐一个网站查看指定城市的经纬度:http://www.jsons.cn/lngcode/
1、geoadd 添加地理位置
语法:GEOADD key 经度 纬度 城市名称 …
注意:南北极无法直接添加。用添加城市数据来说,一般都会使用Java的Jedis来操作,而这些城市数据都是被下载下来通过Java程序一次性导入。
有效经度从-180到180度
有效纬度从-85.05112878 到 85.05112878 度。超过范围会出现(error) ERR invalid longitude,latitude pair
2、geodist
单位:m表示单位米、km表示千米、mi表示英里、ft表示英尺
语法:GEODIST key member1 member2 [unit]
127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing 121.47 31.23 shanghai
1
127.0.0.1:6379> GEODIST china:city beijing shanghai # 单位米
1067378.7564
127.0.0.1:6379> GEODIST china:city beijing shanghai km # 单位千米
1067.3788
1
2
3
4
5
6
7
3、georadius
自己所在的地址为圆心,半径查找
对于社交软件来说,附近的人,就相当于,你现在所在的地址,再加上一定的半径来进行查找
GEORADIUS key 经度 纬度 半径 [单位] [WITHCOORD(搜寻到的目标的经纬度)] [WITHDIST(直线距离)] [count]
127.0.0.1:6379> GEORADIUS china:city 111 31 1000 km
127.0.0.1:6379> GEORADIUS china:city 111 31 1000 km WITHCOORD WITHDIST
127.0.0.1:6379> GEORADIUS china:city 111 31 1000 km WITHCOORD WITHDIST count 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
4、GEORADIUSBYMEMBER
找出指定元素周围的其他元素,就是以城市为中心,一定长度为半径搜索
127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 1000 km
集合中包含的不重复元素即为基数,就比如一个A数据集,A{1,3.7,9,11},它的基数为5,可以接受误差
Hyperloglog是Redis2.8.9更新的,它是一种数据结构,主要是针对于基数统计的算法
优点,占用的内存很小,只需要使用12KB的内存即可统计2^64的数据
在实际业务中,网页的UV(Unique Visitor,独立访客),一个人访问一个网站多次,只能算作是一个,用传统的方式,set集合保存用户的id,然后统计set中元素个数作为标准来判断。使用这种方式来进行数据统计的话,大量的内存用来浪费给保存用户id了,目的是为了计数,而不是为了保存用户id
Hyperloglog计数的错误率在0.81%,用来执行UV任务,可以忽略不计
关键词 命令 作用
pfadd PFADD key value1 value2… 创建一组数据集,如果数据集中有相同的元素就会有去重效果
pfcount PFCOUNT key 查看元素的长度
pfmerge PFMERGE key3 key1 key2 将两组元素合并成一个新数组,并带有去重效果,相当于数学中的并集
127.0.0.1:6379> pfadd pf1 a b c d e f g h i j # 创建
1
127.0.0.1:6379> pfcount pf1 # 查看元素的长度
10
127.0.0.1:6379> pfadd pf2 1 2 3 4
1
127.0.0.1:6379> PFMERGE pf1 pf2 # 合并数组
OK
127.0.0.1:6379> pfcount pf1
14
1
2
3
4
5
6
7
8
9
10
如果在项目中允许容错,可以使用Hyperloglog
如果不行,就可以直接使用set或者Java的HashMap来实现
5.3 Bitmaps
Bitmaps是一种位存储的数据类型,在Redis2.2.0被推出,
生活中可以实现的场景,统计活跃用户,在线状态,用户签到,这些都是表示两种状态之间的,可以使用Bitmaps
Bitmaps,译为位图,也是一种数据结构,操作二进制位进行记录,只有0和1两种状态。Bitmaps通过最小的单位bit来进行存储,表示元素对应的状态
关键词 命令 作用
setbit SETBIT key offset value 设置一个key,在指定的offset位置上设置一个value,这个value只能是0或者1
getbit GETBIT key offset 获取指定key上的offset位的value值
bitcount BITCOUNT key [start] [end] 在指定key中计算被设置为 1 的比特位的数量。
bitop BITOP operation destKey key1 key2 … 对一个或者多个key进行二进制的逻辑运算
bitpos BiTPOS key bit [start] [end] 指定key中返回value中第一个出现0或1的offset
1、
127.0.0.1:6379> setbit bit1 3 0
0
127.0.0.1:6379> getbit bit1 3
0
127.0.0.1:6379> setbit bit1 2 1
0
127.0.0.1:6379> bitcount bit1
1
127.0.0.1:6379> BITPOS week 1 0 -1
4
1
2
3
4
5
6
7
8
9
10
11
12
2、BITOP逻辑运算
一共有4种逻辑运算,AND、OR、NOT、XOR,分别代表 并、或、非、异或
127.0.0.1:6379> SETBIT bit-1 0 1
(integer) 0
127.0.0.1:6379> BITOP AND and-bit bit1 bit2 # 对bit1和bit2进行并操作 得到 and-bit
127.0.0.1:6379> BITOP OR or-bit bit1 bit2 # 或 操作
127.0.0.1:6379> BITOP NOT not-bit bit1
(integer) 1
备注:BITOP执行命令较慢,因为其时间复杂度为O(n)。
在进行计数时,如果数据量过大,建议直接将其指派到master-slave中的slave节点进行处理,避免阻塞
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
public class JedisTest {
private Jedis jedis;
@BeforeEach
void setup(){
//建立连接
jedis=new Jedis("192.168.186.128", 6379);
//输入密码
jedis.auth("abc123");
//选择库
jedis.select(0);
}
@Test
void testJedis(){
jedis.set("name","小虎");
String name = jedis.get("name");
System.out.println(name);
}
@AfterEach
void close(){
if(jedis!=null){
jedis.close();
}
}
}