redis命令
后台启动
redis-server redis.conf
要配置 redis.conf如下:
bind 0.0.0.0
daemonize yes
requirepass 123456
查看redis进程
ps -ef|grep redis
停止服务:
sudo /etc/init.d/redis-server stop
或
redis-cli -a 123456 shutdown
通过redis-cli(客户端)连接到本地redis数据库,-a用于指定密码
redis-cli -a 123456
测试连接
ping
可视化客户端下载链接,在Windows系统中连
https://github.com/lework/RedisDesktopManager-Windows/releases
我的虚拟机地址192.168.30.129
ifconfig
6379有防火墙,看防火墙状态
sudo ufw status
注意是Ubuntu下的防火墙
防火墙开关
sudo ufw allow 6379
让端口数据通过
sudo ufw enable
启用
sudo ufw disable
关闭
基础
set 001 zhangsan NX NX是不覆盖
del
String类型
1k,2k,4k,。。。。。。1M,2M,3M,。。。。。512M
hash表类型
hash表类型的value存储要用hset和hget,hset key field value,hget key field
hkeys、hvals、hgetall
hexists key field
hdel key field
hash表类型主要存对象和json
List类型
List类型是数据少用数组,多用链表
lpush key element 头插法,rpush尾插法
linsert key before|alter target_element new_element
lindex key index
lpop key,rpop key(lpush和lpop模拟栈,lpush和rpop模拟队列)
lrange key start stop
lset key index element(更改)
llen key(链表长度)
lrem key count element(删几个什么元素,count=0时删全部element,>0或<0是删的方向)
ltrim key start end(修剪,保留)
Set类型
sadd key element
srem key element
smove key1 key2 element(把一个元素从一个集合移到另一个)
smembers key(获取所有元素)
scard key(获取元素数量)
sismember key element(元素在不在这个集合中)
srandmember key count(>0一次性取几个,<0取几个但一次一次取)元素还在集合中
spop key count(随机取几个)元素不在集合中了
sinter 集合求交集
sunion 并集
sdiff 差集
有序集合
zadd key score member(每个元素有分值)
zrem key member
zscore key member
zrank key member、zrevrank key member
zrange key start end、zrevrange key start end
zrangebyscore key min max、zrevrangebyscore key max min
zcount key min max
可以用括号,(,无穷大,+inf
上面操作值,下面操作键
exists key
keys pattern(找键,输出键,通配符?、*)
rename key newkey(改键)
renamenx key newkey
expire key seconds(设置有效期)
pexpire key seconds(毫秒)
persist key(永久)
层级key
用 :
set user:1 amy
set user:2 bob
HyperLogLog
统计基数的集合,例如网址访问量
pfadd key element(添加键值对到HyperLogLog对象中)
pfcount key (查看基数)
排序
sort key asc 不会影响列表本身的数据,只影响结果
sort names alpha asc 排字符串的列表
limit 开始 数量(排完后数据很多时要用它)
切换16个数据库
select 1
事务
multi
discard撤销全部
exec
watch用于隔离,如果一个值在其他地方改了,我就不改了
持久化方法
AOF
把写操作存在文件里,redis服务器去读
开启AOF,把redis.conf的appendonly设为yes
appendonly yes
持久化文件名是appendonly.aof
具体操作
修改redis.conf文件,在其中编写如下配置信息
appendonly yes #启动AoF持久化机制
appendfsync everysec #设置了持久化的策略,即持久化的频率是“每秒
dir ./ #设置了持久化文件的保存路径
重启redis
RDB
二进制快照存入硬盘
具体操作
save生成快照
bgsave
在redis.conf里配置生成快照的时间
sava 100 1
Docker
镜像image
从Docker hub获取镜像
docker pull
docker images 查看本地镜像
docker image rm 注意只有该镜像产生的容器都不存在了才能删除该镜像
容器container
用镜像创建并启动容器
docker run
docker run -it --rm ubuntu:22.04 bash
-it:这是两个参数,一个是-i:交互式操作,一个是-t终端。
docker container start 启动已终止的容器
docker container stop
查看容器
docker ps -a
删除
docker rm
安装docker
yum -y install docker
启动docker
service docker start
拿redis镜像
docker pull reids
创建容器
docker run -itd --name redis-test1 -p 6379:6379 redis:latest
-d后台运行
日志
docker logs redis-test1
进入容器里的redis
docker exec -it redis-test1 /bin/bash
进客户端
redis-cli
启动时加载配置文件
docker run -itd --name redis2 -v /home/linfaming/Desktop/server/redis-6.2.7/redis.conf:/redisConfig/redis.conf -p 6379:6379 redis:latest redis-server /redisConfig/redis.conf
redis集群
主从复制
主服务器会把数据赋值给从服务器
创建主服务器
docker run -itd --name redis-master -p 6379:6379 redis:latest
创建从服务器1
docker run -itd --name redis-slave1 -p 6380:6380 redis:latest
创建从服务器2
docker run -itd --name redis-slave2 -p 6381:6381 redis:latest
看主服务器的IP,也叫docker的ip
docker inspect redis-master | grep IPAddress
进入主服务器
docker exec -it redis-master /bin/bash
进从服务器1
docker exec -it redis-slave1 /bin/bash
进从服务器2
docker exec -it redis-slave2 /bin/bash
进客户端
redis-cli
查看redis-cli 信息
info replication
设置主从关系
slaveof 172.17.0.2 6379
(172.17.0.2是主服务器ip,6379是主服务器端口)
这样在第一台机器里写数据,其他也都会写
上面是用命令搭建集群,下面用配置文件搭建集群
先创建主容器
docker run -itd --name redis-master -p 6379:6379 redis:latest
再在server目录(下面有redis-6.2.7)下创建redisSlave1.conf文件,写
port 6380
slaveof 172.17.0.2 6379
文件路径:cd /home/linfaming/Desktop/server/redisSlave1.conf
创建从服务器1
docker run -itd --name redis-slave1 -v /home/linfaming/Desktop/server/redisSlave1.conf:/redisConfig/redisSlave1.conf -p 6380:6380 redis:latest redis-server /redisConfig/redisSlave1.conf
启动客户端时要用
redis-cli -p 16379
哨兵
监听主服务器是否可用,主服务器坏了就升级从服务器
可以多个哨兵
哨兵也是redis集群中的一个
创建配置文件sentinel1.conf
port 16379
sentinel monitor master 172.17.0.2 6379 2
logfile "sentinel1.log"
master 是哨兵名字
172.17.0.2是监听的主机ip
6379 是监听的进程端口
2 是必须两个哨兵都发现有问题才采取行动
改权限
chmod -R 777 /home/linfaming/Desktop/server
创建哨兵集群服务器1
docker run -itd --name redis-sentinel1 -v /home/linfaming/Desktop/server:/redisConfig:z -p 16379:16379 redis:latest redis-server /redisConfig/sentinel1.conf --sentinel
进入容器
docker exec -it redis-sentinel1 /bin/bash
进入客户端
redis-cli -p 16379
看哨兵结点的信息
info sentinel
cluster集群 簇
16384个槽
创建主节点配置文件cluster-m1.conf(m的作为主节点)
port 6379
dir /redisConfig
logfile cluster-m1.log
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-enabled yes是开启cluster功能
多配置几个
创建从节点配置文件(s的作为从节点)
cluster-s1.conf
port 16379
dir /redisConfig
logfile cluster-s1.log
cluster-enabled yes
cluster-config-file nodes-16379.conf
多配置几个
创建容器
docker run -itd --name redis-m1 -v /home/linfaming/Desktop/server:/redisConfig:z -p 6379:6379 redis:latest redis-server /redisConfig/cluster-m1.conf
全部创建
确定每个节点的ip
docker inspect redis-m1 | grep IPAddress
进入redis
docker exec -it redis-m1 /bin/bash
进入客户端
redis-cli
在主节点连接其他节点,要在容器目录下
redis-cli -p 6379 cluster meet 172.17.0.3 6380
redis-cli -p 6379 cluster meet 172.17.0.4 6381
redis-cli -p 6379 cluster meet 172.17.0.5 16379
redis-cli -p 6379 cluster meet 172.17.0.6 16380
redis-cli -p 6379 cluster meet 172.17.0.7 16381
用cluster info输出信息
state为fail,还没分配哈希槽
分配哈希槽
redis-cli -h 172.17.0.2 -p 6379 cluster addslots n ,每次分配一个,用循环
在server目录下创建setHashslots.sh
#!/bin/bash
for i in $(seq 0 5460)
do
/usr/local/bin/redis-cli -h 172.17.0.2 -p 6379 cluster addslots $i
done
16384 / 3 = 5460
执行
bash /redisConfig/setHashslots.sh
cluster nodes查看相连的结点信息
设置从节点
docker exec -it redis-s1 /bin/bash
redis-cli -p 16379
cluster replicate 主id
多做几次
连接时用redis-cli -c,-c是让它随便放哪个结点
Jedis
public class Jedis {
public static void main(String[] args) {
redis.clients.jedis.Jedis jedis = new redis.clients.jedis.Jedis("192.168.30.129", 6379);
jedis.auth("123456");
System.out.println(jedis.ping());
System.out.println(jedis.set("name", "张三"));
System.out.println(jedis.get("name"));
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);//最大连接数
config.setMaxIdle(5);//最大空闲连接数
config.setMaxWaitMillis(100);//最大等待时间毫秒
config.setBlockWhenExhausted(false);//连接耗尽时不阻塞
JedisPool pool = new JedisPool(config, "192.168.30.129", 6379);
redis.clients.jedis.Jedis jedis2 = pool.getResource();
jedis2.auth("123456");
jedis2.set("name", "王五");
System.out.println(jedis2.get("name"));
jedis2.sadd("set1","amy","bob");
System.out.println(jedis2.smembers("set1"));
HashMap map =new HashMap();
map.put("k1","zs");
jedis2.hset("h",map);
System.out.println(jedis2.hget("h","k1"));
pool.close();
}
}
Docker里的MySQL
先拉个镜像
再运行容器
docker run -itd -p 3306:3306 --name mysql --privileged=true -e MYSQL_ROOT_PASSWORD=123456 mysql:latest
进入容器
docker exec -it mysql /bin/bash
执行mysql
mysql -u root -p
输入密码
设置远程连接权限
grant all on *.* to 'root'@'%';
flush privileges;
利用redis做mysql的缓存
在mysql取出数据后封装成对象,再用jedis的hash来存
取数据
- 去redis里取,取不到就去mysql里取,mysql取到的话要存到redis里
从mysql里取数据前先去redis里取
用jedis先判断key存在否,存在才用jedis来get,但是get出来的可能是字符串,要用工具类转换
缓存穿透
每次都去要去mysql里取
或查id=-1(缓存里没有,数据库里也没有)
解决:把id=-1也存在redis
缓存雪崩
不考虑缓存有效期导致内存溢出
redis限流
限制时间、连接数量
MySQL主从集群
用docker拉镜像,整容器,用配置文件启动mysql
找两个目录存conf和data文件,
主MySQL服务器的配置文件放在/opt/mysql-m/conf和/opt/mysql-m/data,
从MySQL服务器的配置文件放在/opt/mysql-s/conf和/opt/mysql-s/data
/opt/mysql-m/conf 文件里建my.cnf文件,主服务器的配置文件
[mysqld]
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
server-id=1
log-bin=mysql-master-bin
启动容器
docker run -itd -p 3306:3306 --name mysql-m --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -v /opt/mysql-m/conf:/etc/mysql/conf.d -v /opt/mysql-m/data:/var/lib/mysql mysql:latest
确定服务器ip
docker inspect mysql-m | grep IPAddress
启动MySQL
docker exec -it mysql-m bash
启动客户端
mysql -u root -p
找个position
show master status;
设置远程连接权限
grant all on *.* to 'root'@'%';
flush privileges;
/opt/mysql-s/conf 文件里建my.cnf文件,从服务器的配置文件
[mysqld]
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
server-id=2
log-bin=mysql-master-bin
id不同
启动容器
docker run -itd -p 3316:3306 --name mysql-s --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -v /opt/mysql-s/conf:/etc/mysql/conf.d -v /opt/mysql-s/data:/var/lib/mysql mysql:latest
确定服务器ip
docker inspect mysql-s | grep IPAddress
启动MySQL
docker exec -it mysql-s bash
启动客户端
mysql -u root -p
设置远程连接权限
grant all on *.* to 'root'@'%';
flush privileges;
在从服务器中尝试连主服务器
mysql -h 172.17.0.2 -u root -p
在从服务器里设置从属关系
change master to master_host='172.17.0.2',master_port=3306 ,master_user='root' ,master_password='123456' ,master_log_pos=540 ,master_log_file='mysql-master-bin.000003';
540是主服务器的position
开启复制
start slave;
查看主从复制状态
show slave status\G;
Redis里调用lua脚本
语法:
redis.call('set','name','peter')
文件夹映射
docker run -itd --name redis-lua -v /opt/lua:/lua-script -p 6379:6379 redis:latest
/opt/lua:/lua-script就是文件夹映射,虚拟机/opt/lua下的lua文件映射到docker里/lua-script里面
执行lua脚本
redis-cli --eval /lua-script/文件名
springboot与redis
用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.0</version>
</dependency>
替换jedis
使用RedisTemplate
@RestController
public class RedisController {
@Resource
private RedisTemplate redisTemplate;
@GetMapping("/redis")
public String redis(){
redisTemplate.opsForValue().set("hello","zhangsan");
return "redis";
}
}
设置过期时间
redisTemplate.expire("hello",20,TimeUnit.SECONDS);
Spring Session
解决用户的cookic只在一台服务器的问题,cookic集群
先
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>2.7.0</version>
</dependency>
@GetMapping("/session")
public String session(String username, String password, HttpSession session){
session.setAttribute("username",username);//自动往redis里写入了
return "成功";
}
localhost:8082/session?username=zhangsan&password=1