- 一.将Redis安装在Linux上
- 1_1、使用
- 1.先将Redis下载到本地
- 2.再通过xftp把redis安装包传送到Linux服务器中
- 3.把安装包移到/opt,并解压
- 3.安装gcc和c++环境
- 4.拷贝一份redis.conf到`/usr/local/bin/jjconfig`
- 5.修改配置文件
- 6.启动redis服务器(通过拷贝后的配置文件)
- 7.启动redis客户端来连接redis服务器
- 8 观察redis内启动的进程(`ps -ef|grep redis`)
- 7.关闭redis
- 8.进程观察(观察服务端和客户端)
- 1_2、使用Docker下载redis
- 二、Redis自带压力测试工具:redis-benchmark
- 三、Redis的基础
- 3.1Redis的基础知识
- 3.2 Redis的基本指令
- 3.2 Redis的密码设置
- 3.3 Redis-key的五大基本类型
- 3.3.1 String常用命令
- 3.3.2list列表类型指令
- 3.3.3 set集合类型指令
- 3.3.4 Hash哈希类型指令
- 3.3.5 Zset有序集合类型指令
- 3.4 Redis的三大特殊类型
- 3.4.1 Geospatial地理位置
- 3.4.2Hyperloglog基数统计
- 3.4.3Bitmap位图场景
- 3.5 Redis基本的事务操作
- 3.5.1事务
- 3.5.2 Redis中的事务执行过程
- 3.5.3 Redis的异常命令处理
- 3.5.4 Redis实现乐观锁(watch,unwatch)
- 3.6 Jedis
- 3.6.1 导入jedis依赖
- 3.6.2 开启6379安全组和6379防火墙
- 3.6.3 修改配置文件中的绑定ip地址
- 3.6.4 开启redis服务器
- 3.6.5 测试
- 3.6.6 jedis操作redis的常见指令
- 3.7 springboot启动redis
- 3.7.1勾选或添加依赖
- 3.7.2 配置连接
- 3.7.3 连接测试
- 3.8常用方法
- 3.9关于如何在Redis中保存对象
- 3.10自定义redisTemplate
- 3.11redis工具类
- 4、Redis配置文件详解
- 4.1 开头简单说明(内容默认为空)
- 4.2、网络配置
- 4.3、SSL配置(内容默认为空)
- 4.4、通用配置
- 4.5、快照(rdb)
- 4.6、主从复制
- 4.7、安全
- 4.8、客户限制
- 4.9、内存配置
- 4.10.aof的配置
- 5、持久化
- 5.1持久化之rdb(redis Datebase)
- 5.1.1 手动触发rdb
- 5.1.2 自动触发rdb(重点)
- 5.2持久化之aof(Append only File)
- 5.2.1 appendonly.aof的内容分析
- 5.2.2修复appendonly.aof
- 5.2.1先开启aof功能
- 6、Redis 两种消息通信模式
- 6.1 队列模式
- 6.2 发布订阅模式(pub/sub)
- 7、主从复制
- 7.1、基本理论
- 7.2、集群的配置(多台redis服务器共同工作)
- 7.2.1配置6379、6380、6381这三个配置文件
- 7.2.2 配置主从复制
- 7.2.3 主从复制效果
- 7.2.4 实现主从复制模式
- 8、 哨兵模式
- 8.1 配置哨兵
- 8.2 启动哨兵
- 8.3 测试哨兵
- 8.4 哨兵的全部配置(sentinel.conf)
- 9、缓存穿透和雪崩(后期看书)
2.再通过xftp把redis安装包传送到Linux服务器中点击进入Redis官网
3.把安装包移到/opt,并解压
3.安装gcc和c++环境
- mv redis-6.2.6.tar.gz /opt
cd /opt
tar -zx redis-6.2.6.tar.gz
- ls
4.拷贝一份redis.conf到/usr/local/bin/jjconfig
- yum install gcc-c++
gcc -v
- make
- 确认是否安装成功make install
5.修改配置文件
- redis的默认安装路径:/usr/local/bin/。进入redis的安装路径cd /usr/local/bin
- 将原来的redis.conf拷贝一份到/usr/local/bin/jjconfig中
mkdir jjconfig
cp /opt/redis-6.2.6/redis.conf jjconfig
6.启动redis服务器(通过拷贝后的配置文件)
- 开始编辑拷贝的redis.conf
cd /usr/local/bin/jjconfig
vim redis.conf
- 把配置文件改为后台可以运行
daemonize no改为daemonize yes.修改完后保存并退出(:wq)。
7.启动redis客户端来连接redis服务器即我们不改动原安装包的redis.cof,而是在拷贝后的文件上修改并使用它来启动redis服务器
【注意】一个配置文件只能创建一个redis-server。
redis-server /usr/local/bin/jjconfig/redis.conf
开启一个redis的客户端(redis-cli)
redis-cli -p 6379
8 观察redis内启动的进程(ps -ef|grep redis)【问题1】为什么redis的端口号是6379呢?
7.关闭redis确定redis的服务端和客户端是否开启
ps -ef|grep redis
8.进程观察(观察服务端和客户端)1、在redis客户端环境下的关闭redis服务器:
先关闭客户端shutdown
再关闭服务器exit
2、在主机环境下关闭redis服务器 pkill redis-server
ps -ef|grep redis
netstat -nlt|grep 6379
先在Linux上下载Docker,点击查看下载Docker流程
二、Redis自带压力测试工具:redis-benchmarkdocker pull redis
三、Redis的基础 3.1Redis的基础知识
- 开启redis服务端(redis-server)和客户端(redis-cli)
redis-server /usr/local/bin/jjconfig/redis.conf
redis-cli -p 6379
2.对单机进行测试
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
通过测试我们会发现redis处理请求是非常快的。
3.2 Redis的基本指令
- Redis默认有16个数据库(0-15),且默认使用其中的第0个。
vim /usr/local/bin/jjconfig/redis.conf
【问题1】Redis为什么是单线程的?
Redis是基于内存操作的而不是CPU,Redis的瓶颈是机器的内存和网络带宽。单线程可以避免保存冲突问题,那么可以用单线程为何不用呢。
【问题2】Redis为什么单线程还这么快呢?
多线程就一定比单线程效率高吗?这个是不一定的。关于读取速度:CPU>内存>硬盘。而Redis是把所有的数据都放在内存里面的,多路复用??
1.select 切换数据库 127.0.0.1:6379[3]> select 0 OK 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> select 16 (error) ERR DB index is out of range 127.0.0.1:6379[1]> select 15 OK 2.dbsize查看数据库大小 127.0.0.1:6379[15]> dbsize (integer) 0 3.设置 和获取数据库名set,get 127.0.0.1:6379[15]> set name junjun OK 127.0.0.1:6379[15]> get name "junjun" 4.查看某个数据库的所有的(keys) 127.0.0.1:6379[1]> keys * 1) "name" 5.清空当前数据库中所有的内容(flushdb) 127.0.0.1:6379[1]> flushdb OK 6. 清空全部的数据库(flushall) 127.0.0.1:6379[1]> flushall OK 7.判断是否存在name这么一个key(exists) 127.0.0.1:6379> exists name (integer) 1 8.使得name在10s之后过期(expire) 127.0.0.1:6379> expire name 10 (integer) 1 9.查看name还有多久过期(-1不会过期,-2已经过期)(ttl) 127.0.0.1:6379> ttl age (integer) -1 10.查看数据类型(type) 127.0.0.1:6379> type age string 11.设置密码(config set requirepass) 172.17.17.120:6379> config set requirepass "3333" OK3.2 Redis的密码设置 3.3 Redis-key的五大基本类型
3.3.1 String常用命令redis是一个典型的key-value键值对
1.拓展字符串内容(返回字符串的总长度) 127.0.0.1:6379> append name 11 (integer) 4 2.查看字符串的长度 127.0.0.1:6379> strlen name (integer) 4 3.实现value中数字加 、减的效果(incr、decr、incrby、decrby) 127.0.0.1:6379> set view 0 OK 127.0.0.1:6379> type view string 127.0.0.1:6379> incr view (integer) 1 127.0.0.1:6379> type view string 127.0.0.1:6379> incr view (integer) 2 127.0.0.1:6379> incr view #自增1 (integer) 3 127.0.0.1:6379> get view "3" 127.0.0.1:6379> decr view (integer) 2 127.0.0.1:6379> get view "2" 127.0.0.1:6379> incrby view 10 #自增10 (integer) 12 4.截取字符串 127.0.0.1:6379> get key1 "hello,jjj" 127.0.0.1:6379> getrange key1 0 4 #截取字符串 "hello" 127.0.0.1:6379> getrange key1 0 -1 #获取全部的字符串 "hello,jjj" 5.替换字符串 127.0.0.1:6379> getrange key1 0 -1 #获取全部的字符串 "hello,jjj" 127.0.0.1:6379> setrange key1 2 aaa #偏移量为2, (integer) 9 127.0.0.1:6379> get key1 "heaaa,jjj" 6.若不存在则创建key,否则这条指令将不生效(防止覆盖操作) 127.0.0.1:6379> setnx key1 "111" (integer) 1 127.0.0.1:6379> get key1 "111" 127.0.0.1:6379> setnx key2 "222" (integer) 0 127.0.0.1:6379> get key2 "60" 7.创建key的值,并设置xxs之后过期(setex) 127.0.0.1:6379> setex key1 50 "jun" OK 127.0.0.1:6379> get key1 "jun" 127.0.0.1:6379> ttl key1 (integer) 42 8.多重创建和多重获取key值(set是一起成功或者一起失败) 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> keys * 1) "k1" 2) "k3" 3) "k2" 127.0.0.1:6379> mget k1 k3 1) "v1" 2) "v3" 127.0.0.1:6379> 9.获取key的当前值然后附上新值 127.0.0.1:6379> getset k1 vvvvv "v1" 127.0.0.1:6379> get k1 "vvvvv"3.3.2list列表类型指令
1.左右入栈lpush,rpush(返回这个列表中元素的数量) 127.0.0.1:6379> lpush list1 a (integer) 1 127.0.0.1:6379> lpush list1 b (integer) 2 127.0.0.1:6379> lpush list2 aa (integer) 1 127.0.0.1:6379> lpush list2 bb (integer) 2 127.0.0.1:6379> keys * 1) "list2" 2) "list1" 2.左右出栈lpop,rpop(返回出栈的元素) 127.0.0.1:6379> lpop list1 "b" 3.根据下标查找(lindex,下标从0开始) 127.0.0.1:6379> lindex list1 1 "b" 4.得到列表的长度 127.0.0.1:6379> llen list1 (integer) 4 5.获取列表的“子串” 127.0.0.1:6379> lrange list1 0 -1 1) "b" 2) "a" 6.删除列表中的一个或多个具体的值。 127.0.0.1:6379> lrange list1 0 -1 1) "c" 2) "c" 3) "b" 4) "a" 5) "d" 127.0.0.1:6379> lrem list1 1 "c" #删除list1中的1个"c" (integer) 1 127.0.0.1:6379> lrange list1 0 -1 1) "c" 2) "b" 3) "a" 4) "d" 7.截取原列表保留子串。 127.0.0.1:6379> Rpush mylist "hello1" (integer) 1 127.0.0.1:6379> Rpush mylist "hello2" (integer) 2 127.0.0.1:6379> Rpush mylist "hello3" (integer) 3 127.0.0.1:6379> Rpush mylist "hello4" (integer) 4 127.0.0.1:6379> ltrim mylist 1 2 #只保留了mylist中下标是1和2的值 OK 127.0.0.1:6379> lrange mylist 0 -1 1) "hello2" 2) "hello3" 8.复合指令。 127.0.0.1:6379> lrange mylist 0 -1 1) "hello2" 2) "hello3" 127.0.0.1:6379> rpoplpush mylist mylist #先出栈,再入栈,把两个语句合并了。 "hello3" 127.0.0.1:6379> lrange mylist 0 -1 1) "hello3" 2) "hello2" 9.只有当该列表和下标存在时才能生效,否则报错 127.0.0.1:6379> lset list 0 "hhh" (error) ERR no such key 127.0.0.1:6379> lpush list "a" (integer) 1 127.0.0.1:6379> lset list 0 "hhh" OK 127.0.0.1:6379> lset list 1 "xxx" (error) ERR index out of range 10.插入到列表中某个元素的前面或者后面 127.0.0.1:6379> linsert mylist before "world" "hello" #在"world"前面插入"hello" (integer) 3 127.0.0.1:6379> linsert mylist after "world" "xx" (integer) 43.3.3 set集合类型指令 3.3.4 Hash哈希类型指令 3.3.5 Zset有序集合类型指令 3.4 Redis的三大特殊类型 3.4.1 Geospatial地理位置 3.4.2Hyperloglog基数统计 3.4.3Bitmap位图场景 3.5 Redis基本的事务操作 3.5.1事务
3.5.2 Redis中的事务执行过程
- 事务的ACID特性:atomicity原子性 consistency一致性 isolation隔离性 durability持久性
3.5.3 Redis的异常命令处理Redis中的事务执行过程:1.开启事务 2.任务入队 3.执行事务
【注意】discord指令可以在任务编辑时取消事务。
命令出现编译型异常:指令存在语法错误,那么事务中所有的指令都不会被执行
命令出现运行时异常:指令不存在语法错误,其他指令能够执行
3.5.4 Redis实现乐观锁(watch,unwatch)【问题1】Redis的单条命令保证原子性,但是事务是不一定保证原子性?
事务的原子性是指:一组命令要都全部执行,要么全都不执行。而由于Redis并不支持事务回滚机制,当出现运行时异常时就不支持原子性了;而 MySQL 的事务是具有原子性的(能回滚),所以大家都认为 Redis 事务不支持原子性。
3.6 Jedis1、redis是单线程,但是在处理多个进程时也要考虑使用锁。
2、乐观锁与悲观锁的概念
【悲观锁】:只要我们开启事务时就将线程中的变量锁住,等事务提交后才解锁
【乐观锁】:当我们开启事务时不锁住变量,但是当我们提交事务时发现发生脏读、不可重复读和幻读等情况时就放弃提交。
3、watch可以看做是Redis的乐观锁操作。使用watch监视之后,它会保存被监视者的值,当我们准备执行更改被监视者值的事务时,watch会进行比较判断这个值是否被在事务开启之后被其他进程修改过。当事务提交完毕后就会自动解锁。
使用unwatch可以对被监视者进行解锁。当我们在事务中要用其他线程修改被监视者时,可以考虑先解除监视,在其他线程修改完后,再次进行监视。
3.6.1 导入jedis依赖Jedis是我们通过java来操控redis的开发工具
3.6.2 开启6379安全组和6379防火墙redis.clients jedis 3.7.0 com.alibaba fastjson 1.2.62
3.6.3 修改配置文件中的绑定ip地址1、打开安全组的6379
2、打开防火墙的6379
点击查看我为什么要修改配置
3.6.4 开启redis服务器总而言之一句话,我们只能通过conf配置文件绑定的ip地址才能使用conf配置文件来开启redis。当然,我们是通过公网来访问Linux服务器的,但是conf配置文件中要绑定私网才行(不能绑定公网)。
1.复制一份配置来专门作为jedis远程连接使用。
cp /usr/local/bin/jjconfig/redis.conf /usr/local/bin/jjconfig/redis_jedis.conf
2.更改
vim /usr/local/bin/jjconfig/redis_jedis.conf而不是
vim /opt/redis-6.2.6/redis.conf哦
3.6.5 测试redis-server /usr/local/bin/jjconfig/redis_jedis.conf
ps -ef|grep redis
3.6.6 jedis操作redis的常见指令jedis中的方法就是redis中的指令。
3.7 springboot启动redis 3.7.1勾选或添加依赖
3.7.2 配置连接org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools runtime true org.springframework.boot spring-boot-configuration-processor true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
spring.redis.host=127.0.0.1 spring.redis.port=63793.7.3 连接测试
@SpringBootTest
class Redis01ApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
System.out.println(redisTemplate.getConnectionFactory().getConnection().ping());
}
}
3.8常用方法
//1. 选择操作对象
ValueOperations valueOperations = redisTemplate.opsForValue();//操作字符串
ListOperations listOperations = redisTemplate.opsForList();//操作List
//2.常用操作和Linux一样的指令
valueOperations.set("k1","v1");
//3.获取redis的连接对象
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
connection.flushDb();
connection.flushAll();
System.out.println(redisTemplate.opsForValue().get("k1"));
3.9关于如何在Redis中保存对象
3.10自定义redisTemplate1.将对象转换成json格式再传入.输出结果形式:{"name":"菌菌","age":3}
2.将对象实现Serializable接口,再直接传入。输出结果形式:User(name=菌菌, age=3)
@Configuration
public class RedisConfig {
//编写自己的redisTemplate配置文件,实现让原User不用实现Serializable接口也能正常输出。
@Bean(name = "redisTemplate01")
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
// JSON序列化配置 不需要被,不需要知道具体参数含义 大概知道是做什么的就可以 这个就是采用JSON序列化对象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String的序列化配置
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 所有的Key通过String序列化
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// 所有的value通过JSON序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
// 调用刚才看的序列化源码中默认的方法,重新设置序列化
template.afterPropertiesSet();
return template;
}
}
3.11redis工具类
设计java工具类是进一步封装 redisTemplate 的操作。
【注意】这是个从网上扒下来的样板,有一个报错 .能看懂即可,每个公司都会有自己的封装方式。
2.传入String... key是指传入一个不定参数的数组。
一维数组的类型是[Ljava.lang.String,二维数组的类型是`
package com.example.redis_01.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
// =============================common============================
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));//报错
}
}
}
// ============================String=============================
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于");
}
return redisTemplate.opsForValue().increment(key, delta);
}
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
public Map
4、Redis配置文件详解
4.1 开头简单说明(内容默认为空)
4.2、网络配置
4.3、SSL配置(内容默认为空)
4.4、通用配置
4.5、快照(rdb)
4.6、主从复制快照机制就是一种持久化的机制:即当在规定的时间内执行了多少次操作就会将数据库中数据持久化一次。redis是内存数据库,那没有持久化不就断电就丢失了吗。
4.7、安全
4.8、客户限制redis默认没有密码我们可以设置密码
4.9、内存配置
4.10.aof的配置noeviction:直接返回错误,不淘汰任何已经存在的redis键
allkeys-lru:所有的键使用lru算法进行淘汰
volatile-lru:有过期时间的使用lru算法进行淘汰
allkeys-random:随机删除redis键
volatile-random:随机删除有过期时间的redis键
volatile-ttl:删除快过期的redis键
volatile-lfu:根据lfu算法从有过期时间的键删除
allkeys-lfu:根据lfu算法从所有键删除
5、持久化
5.1持久化之rdb(redis Datebase)Redis支持RDB和AOF两种持久化机制有效避免数据丢失问题。RDB可以看作在某一时刻Redis的快照(snapshot),非常适合灾难恢复。AOF则是写入操作的日志。
点击查看rdb的原理
5.1.1 手动触发rdbrdb 保存的文件的默认名是dump.rdb,当然我们也可以修改redis.conf中的内容。
5.1.2 自动触发rdb(重点)关于rdb可以有手动保存和自动保存这两种方式。
手动保存可以用save,或shutdown。客户端编辑模式下如果是意外退出(如ctrl+c)就不会持久化了,但是如果是用shutdown命令正常退出就能够实现持久化(会生成或更新dump.rdb文件)。默认用shutdown save,当然我们也可以用shutdown nosave不保存而退出。
5.2持久化之aof(Append only File) 5.2.1 appendonly.aof的内容分析查看redis.conf源码就能发现,我们可以使用save来配置redis的rdb的自动触发方式。
5.2.2修复appendonly.aof如果说rdb是保存的内容,那么aof其实就是一个日志文件。
aof的思想是把我们的所有命令(写操作)都记录下来,当需要恢复时只需要就把这个文件中的指令全部执行一遍就行了。
5.2.1先开启aof功能 6、Redis 两种消息通信模式 6.1 队列模式 6.2 发布订阅模式(pub/sub)当appendonly.aof出现错误导致我们不能成功开启redis,我们就能够使用redis-check-aof --fix来进行修复。
redis-check-aof --fix
7、主从复制 7.1、基本理论1.就像是广播模型,有点像是公众号的形式,所有订阅者都能接受到发布者的发送信息。
2.关于redis-server的内部原理。
7.2、集群的配置(多台redis服务器共同工作)
- 主从复制是什么?
主从复制是指把(Master)主节点上的内容复制到(slave)从节点上去(只能单项复制)。
主节点用来只写,从节点用来只读。
一个主节点至少要两个从节点,一个从节点只能有一个子节点- 主从复制的作用是什么?
…
7.2.1配置6379、6380、6381这三个配置文件我们只要配置Slave,因为在主机上配置的redis服务器默认都是Master。
info replication
7.2.2 配置主从复制
我们将6380,6381配置为6379的从机
slaveof 127.0.0.1 6379
7.2.3 主从复制效果1.如果我们直接在配置文件里面改就能实现永久的效果了,而使用命令配置只能实现暂时实现配置主节点的效果。
2.slaveof no one可以实现从从机转变成主机
7.2.4 实现主从复制模式1、从机只能读不能写
2、主机断掉了,从机还是从机,不能写入数据。主机断线重连,主机还是主机。
3、暂时从机断线重连就不是从机了,永久从机断线重连仍是从机
3、一台新的从机生成时,会立马执行主从复制效果(全量复制)。
8、 哨兵模式
8.1 配置哨兵当主机崩了,从机会自动选出一个新的主机。
8.2 启动哨兵1.创建sentinel.conf文件vim sentinel.conf,编辑内容如下
# sentinel monitor 被监视的名称 ip 端口 1(代表要选举出1个master) sentinel monitor myredis 127.0.0.1 6379 1
8.3 测试哨兵/usr/local/bin/redis-sentinel ./jjconfig/sentinel.conf
8.4 哨兵的全部配置(sentinel.conf)1、我们可以把主机给关了,这时就会发现哨兵会进行选举,其中一台从机变成了主机。
2、在暂时主从复制下:主机重连后,也不能成为老大,只能以成为从机的方式加入集群(slaveof)。、
在永久主从复制下:没测试过。
#配置端口 port 26379 #以守护进程模式启动 daemonize yes #日志文件名 logfile "sentinel_26379.log" #存放备份文件以及日志等文件的目录 dir "/opt/redis/data" #监控的IP 端口号 名称 sentinel通过投票后认为mater宕机的数量,此处为至少2个 sentinel monitor mymaster 192.168.14.101 6379 2 #30秒ping不通主节点的信息,主观认为master宕机 sentinel down-after-milliseconds mymaster 30000 #故障转移后重新主从复制,1表示串行,>1并行 sentinel parallel-syncs mymaster 1 #故障转移开始,三分钟内没有完成,则认为转移失败 sentinel failover-timeout mymaster 1800009、缓存穿透和雪崩(后期看书)
原理:查找时在缓存中没有找到就会自动在数据库中查找,找到后就会写入缓存,否则不写入缓存并返回查找失败。
【缓存穿透】:查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透
【雪崩】:



