本博客根据学习笔记,链接如下
一、Redis常用指令
//启动容器 docker run -d -p 6379:6379 -it --name="myredis" redis 输入密码: auth 密码 //进入redis容器 docker exec -it myredis redis-cli //退出 quit exit //清屏 clear //获得帮助, 可以使用Tab键来切换 help 命令名称 help @组名
二、数据类型
1、String
基本操作
//设置String set key value mset key1 value1 key2 value2... //设置生命周期 setex key seconds value //得到String get key mget key1 key2... //删除String del key ///在字符串后面添加字符,如果有,就补在后面,如果没有,就新建 append key value
string 类型数据的扩展操作
///增长指令,只有当value只有数字才能增长 incr key incrby key increment incrbyfloat key increment //减少指令,有当value减少数字 decr key decrby key increment
- string在redis内部存储默认是,遇到增减操作时incr,decr时会进行计算。
- redis所有的操作都是的,采用在处理所有业务时,命令是一个接一个地执行的,因此无需考虑并发数据的影响。
- 注:如果原始数据不能转换为数值或超过数值,则按数值操作的数据redis 上限范围的数值,将报错。 9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)
- redis控制数据库表主键id,数据库表主键,保障数据库表的主键
- 该方案适用于所有数据库,并支持数据库集群
////设置数据的生命周期,单位 秒 setex key seconds value ////设置数据的生命周期,单位 毫秒 psetex key milliseconds value
- redis 控制数据的生命周期,通过数据是否失效来控制业务行为,适用于所有具有及时性限制的操作
命名规范
2、Hash
基本操作
//插入(如果有同名field,会被覆盖) hset key field value hmset key field1 value1 field2 value2... //插入(如果有同名field,不会被覆盖) hsetnx key field value //取出 hget key field hgetall key //删除 hdel key field1 field2... //获取field数量 hlen key //检查是否存在 hexists key field ///在哈希表中获取所有字段名或字段值 hkeys key hvals key ///设置指定字段的数值数据,增加指定范围内的值 hincrby key field increment hdecrby key field increment
hash 类型数据操作注意事项
- hash类型下的value,不允许存储其他数据类型,。如果数据未获取到, 对应的值为(nil)
- 每个 hash 可以存储 2^32 - 1 个键值
- hash该类型非常接近对象的数据存储形式,并且可以灵活除对象的属性。hash设计的初衷不是为了存储大量的对象而设计的,,更
- hgetall 如果内部是,操作可以获得所有属性field过多,遍历整体,数据访问有可能成为瓶颈
3、List
- 数据存储需求:存储多个数据,区分数据进入存储空间的顺序
- 所需的存储结构:存储空间保存多个数据,并通过数据反映进入顺序
- list类型:保存多个数据,底层采用双向链表存储结构
基本操作
//添加修改数据,lpush从左边加,rpush从右边加 lpush key value1 value2 value3... rpush key value1 value2 value3... ///查看数据, 从左到右检查. 如果不知道list有多少元素,end值可为-1,代表倒数第一元素 //lpush先进元素放在最后,rpush先进元素放在前面 lrange key start end //得到长度 llen key ////取出相应索引的元素 lindex key index //获取并移除元素(从list移除左或右) lpop key rpop key
拓展操作
///在规定的时间内获取和删除数据,b=block,给定时间,如果在指定时间内放置元素,则删除 blpop key1 key2... timeout brpop key1 key2... timeout //移除指定元素 count:移除的个数 value:移除的值。 从左侧移除多个相同元素时 lrem key count value
注意事项
- list保存在中的数据都是string数据总容量有限,最多2^32 - 1 个元素 (4294967295)。
- list它有索引的概念,但通常用于操作数据以入队的形式出队(rpush, rpop)操作,或以进出栈的形式(lpush, lpop)操作
- 所有数据操作结束索引设置为-1 (倒数第一元素)
- list数据可以分页操作。通常,第一页的信息来自list,以数据库的形式加载第二页和更多信息
4、Set
基本操作
//添加元素 sadd key member1 member2... ///检查元素 smembers key ///去除元素 srem key member ///检查元素个数 scard key ///检查某个元素是否存在 sismember key member
扩展操作
//从set中任意选出count个元素 srandmember key count //从set中任意选出count并去除个元素 spop key count ///两集交集,并集,差集 sinter key1 key2... sunion key1 key2... sdiff key1 key2... //求两个set交集、并集、差集,放另一个set中 sinterstore destination key1 key2... sunionstore destination key1 key2... sdiffstore destination key1 key2... / smove source destination key
5sorted_set
- 新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行的方式
- 需要的存储结构:新的存储模型,可以保存的数据
- sorted_set类型:在set的存储结构基础上添加可排序字段
基本操作
//插入元素, 需要指定score(用于排序)
zadd key score1 member1 score2 member2
//查看元素(score升序), 当末尾添加withscore时,会将元素的score一起打印出来
zrange key start end (withscore)
//查看元素(score降序), 当末尾添加withscore时,会将元素的score一起打印出来
zrevrange key start end (withscore)
//移除元素
zrem key member1 member2...
//按条件获取数据, 其中offset为索引开始位置,count为获取的数目
zrangebyscore key min max [withscore] [limit offset count]
zrevrangebyscore key max min [withscore] [limit offset count]
//按条件移除元素
zremrangebyrank key start end
zremrangebysocre key min max
//按照从大到小的顺序移除count个值
zpopmax key [count]
//按照从小到大的顺序移除count个值
zpopmin key [count]
//获得元素个数
zcard key
//获得元素在范围内的个数
zcount min max
//求交集、并集并放入destination中, 其中numkey1为要去交集或并集集合的数目
zinterstore destination numkeys key1 key2...
zunionstore destination numkeys key1 key2...
- min与max用于限定搜索查询的
- start与stop用于限定,作用于索引,表示开始和结束索引
- offset与count用于限定查询范围,作用于查询结果,表示和
拓展操作
//查看某个元素的索引(排名)
zrank key member
zrevrank key member
//查看某个元素索引的值
zscore key member
//增加某个元素索引的值
zincrby key increment member
注意事项
- score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992
- score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,,使用时候要
- sorted_set 底层存储还是结构的,因此数据,如果重复添加相同的数据,score值将被反复覆盖,修改的结果
三、通用指令
1、Key的特征
- key是一个,通过key获取redis中保存的数据
2、Key的操作
基本操作
//查看key是否存在
exists key
//删除key
del key
//查看key的类型
type key
拓展操作(时效性操作)
//设置生命周期
expire key seconds
pexpire key milliseconds
//查看有效时间, 如果有有效时间则返回剩余有效时间, 如果为永久有效,则返回-1, 如果Key不存在则返回-2
ttl key
pttl key
//将有时限的数据设置为永久有效
persist key
拓展操作(查询操作)
//根据key查询符合条件的数据
keys pattern
拓展操作(其他操作)
//重命名key,为了避免覆盖已有数据,尽量少去修改已有key的名字,如果要使用最好使用renamenx
rename key newKey
renamenx key newKey
//查看所有关于key的操作, 可以使用Tab快速切换
help @generic
3、数据库通用操作
数据库
- Redis为每个服务提供有16个数据库,编号从0到15
- 每个数据库之间的数据相互独立
基本操作
//切换数据库 0~15
select index
//其他操作
quit
ping
echo massage
拓展操作
//移动数据, 必须保证目的数据库中没有该数据
mov key db
//查看该库中数据总量
dbsize
三、Jedis
操作Redis需要导入jar或引入Maven依赖
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
1、Java操作redis的步骤
- 连接Redis
//参数为Redis所在的ip地址和端口号
Jedis jedis = new Jedis(String host, int port)
- 操作Redis
//操作redis的指令和redis本身的指令几乎一致
jedis.set(String key, String value);
- 断开连接
jedis.close();
2、配置工具
- 配置文件
redis.host=47.103.10.63
redis.port=6379
redis.maxTotal=30
redis.maxIdle=10
- 工具类
public class JedisUtils {
private static JedisPool jp = null;
private static String host;
private static int maxTotal;
private static int maxIdle;
static {
ResourceBundle rb = ResourceBundle.getBundle("redis");
host = rb.getString("redis.host");
int port = Integer.parseInt(rb.getString("redis.port"));
maxTotal = Integer.parseInt(rb.getString("redis.maxTotal"));
maxIdle = Integer.parseInt(rb.getString("redis.maxIdle"));
JedisPoolConfig jpc = new JedisPoolConfig();
jpc.setMaxTotal(maxTotal);//最大连接数
jpc.setMaxIdle(maxIdle);//活动连接数
jp = new JedisPool(jpc,host,port);
}
public static Jedis getJedis(){
return jp.getResource();
}
}
案例
package com.jzt.jedisStudy;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisDataException;
public class Service {
String id ;
int num;
public Service(String id,int num){
this.id = id;
this.num = num;
}
//控制单元
public void service(){
Jedis jedis = new Jedis("localhost", 6379);
String value = jedis.get("compid:"+id);
//判断该值是否存在
try {
//不限次用户不走下面判断
if(value == null){
//不存在
jedis.setex("compid:"+id,5,Long.MAX_VALUE - num + "");
}else{
//存在,自增,调用业务
Long val = jedis.incr("compid:"+id);
business(id,num - (Long.MAX_VALUE - val));
}
}
catch (JedisDataException e){
System.out.println("使用到达上限,请升级会员");
return;
}
finally {
jedis.close();
}
}
//业务操作
public void business(String id,Long val){
System.out.println("用户:" +id + "业务操作执行:" + val + "次");
}
}
class MyThread extends Thread{
Service sc;
int num;
public MyThread(String id,int num){
sc = new Service(id,num);
}
@Override
public void run() {
while(true){
sc.service();
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Main{
public static void main(String[] args) {
MyThread mt1 = new MyThread("初级用户",10);
MyThread mt2 = new MyThread("高级用户",20);
mt1.start();
mt2.start();
}
}
Linux
重新生成配置文件,不带注释
cat redis.conf | grep -v "#" | grep -v "^$" > redis-6379.conf
保留如下配置:
redis-server conf/redis-6379.cnf
开多个端口的redis:记得更改端口
redis-server conf/redis-6380.cnf
客户端启动:
redis-cli -p 6380
四、持久化
Redis容器配置redis.conf
-
redis容器里边的配置文件是需要在进来的
停止容器:docker container stop myredis 删除容器:docker container rm myredis
-
重新开始创建容器
1. 创建docker统一的外部配置文件 mkdir -p docker/redis/{conf,data} 2. 在conf目录创建redis.conf的配置文件 touch /docker/redis/conf/redis.conf 3. redis.conf文件的内容需要自行去下载,网上很多 4. 创建启动容器,加载配置文件并持久化数据 docker run -d --privileged=true -p 6379:6379 -v /docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /docker/redis/data:/data --name myredis redis redis-server /etc/redis/redis.conf --appendonly yes
-
文件目录
/docker/redis
1、简介
什么是持久化?
利用存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。
为什么要持久化
数据的意外,确保数据
持久化过程保存什么
- 将当前进行保存,形式,存储数据结果,存储格式简单,关注点在
- 将数据的进行保存,形式,存储操作过程,存储格式复杂,关注点在数据的操作
2、RDB
RDB启动方式——save
-
命令
save
-
作用
手动执行一次保存操作
RDB配置相关命令
- dbfilename dump.rdb
- 说明:设置本地数据库文件名,默认值为 dump.rdb
- 经验:通常设置为dump-端口号.rdb
- dir
- 说明:设置存储.rdb文件的路径
- 经验:通常设置成存储空间较大的目录中,目录名称data
- rdbcompression yes
- 说明:设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩
- 经验:通常默认为开启状态,如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变大(巨大)
- rdbchecksum yes
- 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
- 经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险
RDB启动方式——save指令工作原理
:的执行会当前Redis服务器,直到当前RDB过程完成为止,有可能会造成,线上环境。
RDB启动方式——bgsave
-
命令
bgsave
-
作用
手动启动后台保存操作,但
RDB启动方式 —— bgsave指令工作原理
: 是针对save阻塞问题做的。Redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用,推荐使用bgsave
docker logs myredis
RDB启动方式 ——save配置
-
配置
save second changes
-
作用
满足范围内key的变化数量达到即进行持久化
-
参数
- second:监控时间范围
- changes:监控key的变化量
-
配置位置
在中进行配置
RDB启动方式 ——save配置原理
:
- save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题,结果可能是灾难性的
- save配置中对于second与changes设置通常具有关系(一个大一个小),尽量不要设置成包含性关系
- save配置启动后执行的是
RDB启动方式对比
RDB优缺点
- 优点
- RDB是一个紧凑压缩的二进制文件,
- RDB内部存储的是redis在某个时间点的数据快照,非常适合用于等场景
- RDB恢复数据的要比AOF很多
- 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,
- 缺点
- RDB方式无论是执行指令还是利用配置,,具有较大的可能性丢失数据
- bgsave指令每次运行要执行fork操作,要掉一些
- Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式现象
3、AOF
AOF概念
- AOF(append only file)持久化:以独立日志的方式记录写命令,重启时再重新执行AOF文件中命令,以达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程
- AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的方式
AOF写数据过程
AOF写数据三种策略(appendfsync)
- always
- 每次写入操作均同步到AOF文件中,数据零误差,,
- everysec
- 每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高, ,,也是默认配置
- 在系统突然宕机的情况下丢失1秒内的数据
- no
- 由操作系统控制每次同步到AOF文件的周期,整体过程
AOF功能开启
-
配置
appendonly yes|no
- 作用
- 是否开启AOF持久化功能,
-
配置
appendfsync always|everysec|no
- 作用
- AOF写数据策略
- 作用
AOF重写
作用
- 降低磁盘占用量,提高磁盘利用率
- 提高持久化效率,降低持久化写时间,提高IO性能
- 降低数据恢复用时,提高数据恢复效率
规则
-
进程内已超时的数据不再写入文件
-
忽略
无效指令
,重写时使用进程内数据直接生成,这样新的AOF文件
只保留最终数据的写入命令
- 如del key1、 hdel key2、srem key3、set key4 111、set key4 222等
-
对同一数据的多条写命令合并为一条命令
- 如lpush list1 a、lpush list1 b、 lpush list1 c 可以转化为:lpush list1 a b c
- 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
如何使用
-
手动重写
bgrewriteaof
-
自动重写
auto-aof-rewrite-min-size size auto-aof-rewrite-percentage percentage
工作原理
AOF自动重写
-
自动重写触发条件设置
//触发重写的最小大小 auto-aof-rewrite-min-size size //触发重写须达到的最小百分比 auto-aof-rewrite-percentage percent
-
自动重写触发比对参数( 运行指令info Persistence获取具体信息 )
//当前.aof的文件大小 aof_current_size //基础文件大小 aof_base_size
-
自动重写触发条件
工作原理
缓冲策略
AOF缓冲区同步文件策略,由参数控制
- write操作会触发延迟写(delayed write)机制,Linux在内核提供页缓冲区用 来提高硬盘IO性能。write操作在写入系统缓冲区后直接返回。同步硬盘操作依 赖于系统调度机制,列如:缓冲区页空间写满或达到特定时间周期。同步文件之 前,如果此时系统故障宕机,缓冲区内数据将丢失。
- fsync针对单个文件操作(比如AOF文件),做强制硬盘同步,fsync将阻塞知道 写入硬盘完成后返回,保证了数据持久化。
4、RDB VS AOF
RDB与AOF的选择之惑
-
对数据非常
敏感
,建议使用默认的
AOF
持久化方案
- AOF持久化策略使用,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。
- 注意:由于AOF文件,且
-
数据呈现
阶段有效性
,建议使用RDB持久化方案
- 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且,阶段 点数据恢复通常采用RDB方案
- 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低
-
综合比对
- RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
- 如不能承受数分钟以内的数据丢失,对业务数据非常,选用
- 如能承受数分钟以内的数据丢失,且追求大数据集的,选用
- 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据
五、Redis事务
1、Redis事务的定义
redis事务就是一个命令执行的队列,将一系列预定义命令(一个队列)。当执行时,,中间不会被打断或者干扰
2、事务的基本操作
-
开启事务
multi
- 作用
- 作设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中
- 作用
-
取消事务
discard
- 作用
- 终止当前事务的定义,发生在multi之后,exec之前
- 作用
-
执行事务
exec
- 作用
- 设定事务的结束位置,同时执行事务。,成对使用
- 作用
3、事务操作的基本流程
4、事务操作的注意事项
- 语法错误
- 指命令书写格式有误 例如执行了一条不存在的指令
- 处理结果
- 如果定义的事务中所包含的命令存在语法错误,整体事务中。包括那些语法正确的命令
- 运行错误
- 指命令,但是。例如对list进行incr操作
- 处理结果
- 能够正确运行的命令会执行,运行错误的命令不会被执行
:已经执行完毕的命令对应的数据,需要程序员自己在代码中实现回滚。
5、基于特定条件的事务执行
锁
-
对 key 添加监视锁,在执行exec前如果key发生了变化,终止事务执行
watch key1, key2....
-
取消对key的监视
unwatch
分布式锁
-
使用 setnx 设置一个公共锁
//上锁 setnx lock-key value //释放锁 del lock-key
- 利用setnx命令的返回值特征,有值(被上锁了)则返回设置失败,无值(没被上锁)则返回设置成功
- 操作完毕通过del操作释放锁
:上述解决方案是一种,依赖规范保障,具有风险性
分布式锁加强
-
使用 expire 为锁key添加,到时不释放,放弃锁
expire lock-key seconds pexpire lock-key milliseconds
-
由于操作通常都是微秒或毫秒级,因此该锁定时间。具体时间需要业务测试后确认。
- 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。
- 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时
- 锁时间设定推荐:最大耗时120%+平均网络延迟110%
- 如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可
六、删除策略
1、数据删除策略
- 定时删除
- 惰性删除
- 定期删除
时效性数据的存储结构
- Redis中的数据,在expire中以哈希的方式保存在其中。其value是数据在内存中的地址,filed是对应的生命周期
数据删除策略的目标
在内存占用与CPU占用之间寻找一种,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄露
2、三种删除策略
定时删除
- 创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务对键的删除操作
- 优点:,到时就删除,快速释放掉不必要的内存占用
- 缺点:,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
- 总结:用处理器性能换取存储空间 ()
惰性删除
- 数据到达过期时间,不做处理。等下次访问该数据时
- 如果未过期,返回数据
- 发现已过期,删除,返回不存在
- 优点:,发现必须删除的时候才删除
- 缺点:,出现长期占用内存的数据
- 总结:用存储空间换取处理器性能 (拿空间换时间)
定期删除
- 周期性轮询redis库中的时效性数据,采用,利用过期数据占比的方式控制删除频度
- 特点1:CPU性能占用设置有峰值,检测频度可自定义设置
- 特点2:内存压力不是很大,长期占用内存的冷数据会被持续清理
- 总结:周期性抽查存储空间 (随机抽查,重点抽查)
3、逐出算法
**当新数据进入redis时,如果内存不足怎么办? **
- Redis使用内存存储数据,在执行每一个命令前,会调用
注意 :逐出数据的过程不是100%能够清理出足够的可使用的内存空间,如果不成功则反复执行。当对所有数据尝试完毕后,如果不能达到内存清理的要求,将出现错误信息。
影响数据逐出的相关配置
-
最大可使用内存
maxmemory
占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。
-
每次选取待删除数据的个数
maxmemory-samples
选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据
-
删除策略
maxmemory-policy
达到最大内存后的,对被挑选出来的数据进行删除的策略
影响数据逐出的相关配置
数据逐出策略配置依据
- 使用
INFO命令 输出监控信息,查询缓存hit 和 miss 的次数,根据业务需求调优Redis配置
七、高级数据类型
1、Bitmaps
基础操作
-
获取指定key对应偏移量上的bit值
getbit key offset
-
设置指定key对应偏移量上的bit值,value只能是1或0
setbit key offset value
扩展操作
-
对指定key按位进行交、并、非、异或操作,并将结果
保存到destKey 中bitop op destKey key1 [key2...]
- and:交
- or:并
- not:非
- xor:异或
-
统计指定key中1的数量
bitcount key [start end]
2、HyperLogLog
基数
- 基数是数据集
去重后元素个数 - HyperLogLog 是用来做基数统计的,运用了LogLog的算法
基本操作
-
添加数据
pfadd key element1, element2...
-
统计数据
pfcount key1 key2....
-
合并数据
pfmerge destkey sourcekey [sourcekey...]
相关说明
- 用于进行基数统计,
不是集合,不保存数据 ,只记录数量而不是具体数据 - 核心是基数估算算法,最终数值
存在一定误差 - 误差范围:基数估计的结果是一个带有 0.81% 标准错误的近似值
耗空间极小 ,每个hyperloglog key占用了12K的内存用于标记基数- pfadd命令不是一次性分配12K内存使用,会随着基数的增加内存
逐渐增大 - Pfmerge命令
合并后占用 的存储空间为12K ,无论合并之前数据量多少
3、GEO
基本操作
-
添加坐标点
geoadd key longitude latitude member [longitude latitude member ...] georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]
-
获取坐标点
geopos key member [member ...] georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]
-
计算坐标点距离
geodist key member1 member2 [unit] geohash key member [member ...]
八、主从复制
1、简介
多台服务器连接方案
- 提供数据方:master
- 主服务器,主节点,主库
- 主客户端
- 接收数据的方:slave
- 从服务器,从节点,从库
- 从客户端
- 需要解决的问题
数据同步
- 核心工作
- master的数据
复制 到slave中
- master的数据
主从复制
主从复制即将master中的数据即时、有效的
特征:一个master可以拥有多个slave,一个slave只对应一个master
职责:
- master:
- 写数据
- 执行写操作时,将出现变化的数据自动
同步 到slave - 读数据(可忽略)
- slave:
- 读数据
- 写数据(
禁止 )
2、作用
- 读写分离:master写、slave读,提高服务器的读写负载能力
- 负载均衡:基于主从结构,配合读写分离,由slave分担master