main
tink 1 year ago
parent ed9fd4f317
commit be667815cb

@ -144,13 +144,14 @@ Linux下Buffered IO默认使用的是Write back机制即文件操作的写只
### 1.2 进程上下文切换(进程切换)
  为了控制进程的执行内核必须有能力挂起正在CPU上运行的进程并恢复以前挂起的某个进程的执行。这种行为被称为进程切换也叫调度。因此可以说任何进程都是在操作系统内核的支持下运行的是与内核紧密相关的。
  从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:
1. 保存当前进程A的上下文。
从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:
  上下文就是内核再次唤醒当前进程时所需要的状态,由一些对象(程序计数器、状态寄存器、用户栈等各种内核数据结构)的值组成。
1. 保存当前进程A的上下文
上下文就是内核再次唤醒当前进程时所需要的状态,由一些对象(程序计数器、状态寄存器、用户栈等各种内核数据结构)的值组成。
这些值包括描绘地址空间的页表、包含进程相关信息的进程表、文件表等。
  这些值包括描绘地址空间的页表、包含进程相关信息的进程表、文件表等。
  
2. 切换页全局目录以安装一个新的地址空间。
3. 恢复进程B的上下文。
@ -185,6 +186,7 @@ write过程中会有很多次拷贝直到数据全部写到磁盘。
2. 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
正式因为这两个阶段linux系统产生了下面五种网络模式的方案
- 阻塞 I/Oblocking IO
- 非阻塞 I/Ononblocking IO
- I/O 多路复用( IO multiplexing
@ -308,6 +310,23 @@ select/epoll的优势并不是对于单个连接能处理得更快而是在
- 而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人kernel完成然后他人做完后发信号通知。在此期间用户进程不需要去检查IO操作的状态也不需要主动的去拷贝数据。
## Epoll模式
### Epoll支持的两种操作模式
epoll对文件描述符有两种操作模式
- LTLevel Trigger水平模式
LT是epoll的默认操作模式当epoll_wait函数检测到有事件发生并将通知应用程序而应用程序不一定必须立即进行处理这样epoll_wait函数再次检测到此事件的时候还会通知应用程序直到事件被处理。LT支持阻塞的套接字和非阻塞的套接字。
- ETEdge Trigger边缘模式
ET模式下只要epoll_wait函数检测到事件发生通知应用程序立即进行处理后续的epoll_wait函数将不再检测此事件。因此ET模式在很大程度上降低了同一个事件被epoll触发的次数因此效率比LT模式高。ET只支持非阻塞的套接字。
**ET是状态变化的通知即从没有数据转到有数据会通知LT是数据变化的通知即有数据就通知没数据就不通知**。对于ET模式当接收到通知后应该一直read循环读取直到返回EWOULDBLOCK或EAGAIN这样内部状态才会从有数据再次转为无数据从而为下一次数据的到来做准备否则只有对端再次发送数据时候才会再次触发可读事件。
对于ET状态应该注意防止恶意请求连接防止其一直请求造成其他请求饿死。
## 资料

@ -3,12 +3,15 @@
## redis架构
- 纯内存操作
- 单线程避免了多线程频繁的上小文切换问题
- 单线程避免了多线程因为同步导致的频繁的上下文切换问题
- 高效的数据结构
- 核心是基于非阻塞的IO多路复用
- 核心是基于非阻塞的IO多路复用(epoll)
## 应用场景
![](https://static.cyub.vip/images/202406/redis-case.jpg)
- 缓存
- 队列
- 排行榜
- 自动补全
@ -251,6 +254,66 @@ info commandstats
info keyspace
```
## 基于Redis实现分布式锁的几种方案
基于Redis实现分布式锁的缺点
1. 超时时间不好设置
当线程A获取到锁之后可能业务还没有执行完成锁就过期了
2. 锁可能无法永远无法释放
3. 锁可靠性问题
1. 对于redis cluster集群当线程A刚获取到锁后此时锁所在Master节点恰好挂了数据还没同步到Slave节点而Slave节点恰好升级为主节点导致B线程可以获取到锁。此时A、B线程同时在执行业务
2. 线程A执行完成任务后去释放锁可能是否释放掉了其他线程持有的锁比如线程A执行完成时候锁早已过期线程B获取到了锁
### SETNX + EXPIRE
如果执行完setnx加锁正要执行expire设置过期时间时进程crash或redis挂掉了会到锁永远无法释放。
### SETNX + value值是(系统时间+过期时间)
可以把过期时间放到setnx的value值里面。如果加锁成功再拿出value值校验一下是否过期即可。
### 使用Lua脚本(包含SETNX + EXPIRE两条指令)
### SET的扩展命令SET EX PX NX
> SET key value[EX seconds][PX milliseconds][NX|XX]
- NX :表示key不存在的时候才能set成功也即保证只有第一个客户端请求才能获得锁而其他客户端请求只能等其释放锁才能获取。
- EX seconds :设定key的过期时间时间单位是秒。
- PX milliseconds: 设定key的过期时间单位为毫秒
- XX: 仅当key存在时设置值
XX可以设置当前线程关联的值当要释放锁时候判断当前所锁的关联的值是否是当前线程关联的值如果是才允许释放这解决了3.b问题。可以通过Lua脚本保证这个过程的原子性
```lua
if redis.call('get',KEYS[1]) == ARGV[1] then
return redis.call('del',KEYS[1])
else
return 0
end;
```
### Redisson
给获得锁的线程开启一个定时守护线程每隔一段时间检查锁是否还存在存在则对锁的过期时间延长防止锁过期提前释放。这解决了问题1。
当前开源框架Redisson解决了这个问题。Redisson底层原理如下
![](https://static.cyub.vip/images/202406/redisson.webp)
### Redlock
对于3.a问题Redis作者 antirez提出一种高级的分布式锁算法Redlock。Redlock核心思想如下
> 当一个客户端要获取红锁时,它会尝试在多个 Redis 节点上分别执行 SETNXSET if Not eXists命令如果大多数N/2+1加锁成功了则认为获取锁成功。
## 资料
- [Redis---持久化方式RDB、AOF](https://blog.csdn.net/zhangpower1993/article/details/89034941)
- [七种方案探讨Redis分布式锁的正确使用姿势](https://juejin.cn/post/6936956908007850014)

@ -18,7 +18,7 @@
假定有几台Redis服务器假定是N要存储key-value数据传统模式是根据hash(key)%N服务器数量来定位出来存放在第几台服务器上面。
一致性Hash算法会使用2^32个虚拟hash槽位可以想象成在一个圆环也叫hash环上面有0到2^32-1编号的槽位。首先我们确定每台Redis服务器在这个环上槽位可以用服务器IP或ID或者name进行hash
一致性Hash算法会使用2\^32个虚拟hash槽位可以想象成在一个圆环也叫hash环上面有0到2\^32-1编号的槽位。首先我们确定每台Redis服务器在这个环上槽位可以用服务器IP或ID或者name进行hash
> 槽位 = hash(Redis服务器IP)%2^32
当一个key-value数据过来时候根据key计算出其在环上槽位然后沿着环顺时针行走遇到的第一个服务器就是要存放的服务器。
@ -64,7 +64,7 @@ Cap理论中C代表一致性A代表可用性P代表分区容忍性。CAP
## 什么是Raft算法
Raft算法属于强一致性算法实现。在Raft中每个节点在同一时刻只能处于以下三种状态之一
Raft算法属于最终一致性致性算法实现。在Raft中每个节点在同一时刻只能处于以下三种状态之一
- 领导者(Leader)
- 候选者(Candidate)
@ -224,11 +224,11 @@ saga保证满足以下业务规则
## Consul架构是怎么样的
![](https://learn.hashicorp.com/assets/images/consul-arch.png?ynotemdtimestamp=1627634261331)
![](https://static.cyub.vip/images/202406/consul-arch.png)
- Agent是Consul集群中的守护进程。它的生命周期从启动Consul agent开始。Agent可以以client或是server模式运行
- ClientClient是转发所有RPC请求Server的Agent。Client相对来说是无状态的它的唯一后台活动是参与LAN gossip pool。它的资源开销很小只消耗少量的网络带宽
- ClientClient是转发所有RPC请求Server的Agent。Client相对来说是无状态的它的唯一后台活动是参与LAN gossip pool。它的资源开销很小只消耗少量的网络带宽
- ServerServer是负责参与Raft quorum维护集群状态响应RPC查询和其他datacenter交换WAN gossip信息并转发查询到leader或是远程datacenter的Agent

@ -297,7 +297,7 @@ slow log用来记录慢查询
## 查询语句不同元素where、jion、limit、group by、having等等执行先后顺序
where字句在聚合前先筛选记录也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。
where在聚合前先筛选记录也就是说作用在group by和having前。而 having子句在聚合后对组记录进行筛选。
## Innodb为什么一定需要一个主键且必须自增列作为主键
@ -306,14 +306,14 @@ where字句在聚合前先筛选记录也就是说作用在group by和having
总之Innodb一定需要一个主键。
1. 这是因为数据记录本身被存于主索引一颗B+Tree的叶子节点上这就要求同一个叶子节点内大小为一个内存页或磁盘页的各条数据记录按主键顺序存放
2. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页这样的页称为叶子页)
2. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页(这样的页称为叶子页)
3. 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新记录都要被插到现有索引页得中间某个位置
## 在MVCC并发控制中读操作可以分成哪两类?
快照读 (snapshot read):读取的是记录的可见版本 (有可能是历史版本)不用加锁共享读锁s锁也不加所以不会阻塞其他事务的写
**快照读 (snapshot read)**:读取的是记录的可见版本 (有可能是历史版本)不用加锁共享读锁s锁也不加所以不会阻塞其他事务的写
当前读 (current read):读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
**当前读 (current read)**:读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
## Mysql中DATATIME和TIMESTAP的区别
@ -323,13 +323,15 @@ datetime、timestamp精确度都是秒datetime与时区无关存储的范
- 事务隔离级别设置为SERIALIZABLE 串行化
- MVCC + Next-Key Lock
Next-Key Lock是Gap Lock间隙锁和Record Lock行锁的结合版都属于Innodb的锁机制。
比如select * from tb where id>100 for update
Next-Key Lock(临键锁) 是Gap Lock间隙锁和Record Lock记录锁属于行锁的结合版都属于Innodb的锁机制。 比如select * from tb where id>100 for update
1. 主键索引 id 会给 id=100 的记录加上 record行锁
2. 索引 id 上会加上 gap 锁,锁住 id(100,+无穷大)这个范围,其他事务对 id>100 范围的记录读和写操作都将被阻塞。插入 id=1000的记录时候会命中索引上加的锁会报出事务异常
Next-Key Lock会确定一段范围然后对这个范围加锁保证A在where的条件下读到的数据是一致的因为在where这个范围其他事务根本插不了也删不了数据都被Next-Key Lock锁堵在一边阻塞掉了。
3. Next-Key Lock会确定一段范围然后对这个范围加锁保证A在where的条件下读到的数据是一致的因为在where这个范围其他事务根本插不了也删不了数据都被Next-Key Lock锁堵在一边阻塞掉了。
> 记录锁是行级别的锁row-level locks当InnoDB 对索引进行搜索或扫描时,会在索引对应的记录上设置共享或排他的记录锁。
## Mysql什么时候会取得gap lock或nextkey lock?
@ -504,7 +506,7 @@ KEY分区跟HASH分区类似分区字段可以是除text和BLOB外的所有
## 索引名字规则
```
```sql
idx(a, b, c) HIT where a = x and b = x
idx(a, b, c) HIT where a > x
idx(a, b, c) Not HIT where b > x
@ -520,7 +522,8 @@ idx(a, b, c) Not HIT where a = x group by b
```
mysql建立多列索引联合索引有最左前缀的原则即最左优先
- 如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;
- 如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;
- 如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引;
@ -543,3 +546,7 @@ b+ 树的数据项是复合的数据结构,比如 (name,age,sex) 的时候b
## mysql中悲观锁、乐观锁、共享锁、排他锁有什么区别
![](https://static.cyub.vip/images/202107/mysql-lock.jpg)
## 更多资料
- [MySQL记录锁、间隙锁、临键锁Next-Key Locks详解](https://blog.csdn.net/yzx3105/article/details/129675468)

@ -26,7 +26,7 @@ Kafka是高吞吐低延迟的高并发、高性能的消息中间件配置良
自 Kafka 2.4 之后Kafka 提供了有限度的读写分离也就是说Follower 副本能够对外提供读服务。
1. 业务场景不适用。读写分离适用于那种读负载很大,而写操作相对不频繁的场景,可 Kafka 不属于这样的场景。
2. 同步机制。Kafka 采用 PULL 方式实现 Follower 的同步,因此Follower 与 Leader 存 在不一致性窗口。如果允许读 Follower 副本,就势必要处理消息滞后(Lagging)的问题。
2. 同步机制。Kafka 采用 PULL 方式实现 Follower 的同步因此Follower 与 Leader 存 在不一致性窗口。如果允许读 Follower 副本,就势必要处理消息滞后(Lagging)的问题。
## 如何解决kafka消息重复消费问题
@ -36,7 +36,7 @@ Kafka是高吞吐低延迟的高并发、高性能的消息中间件配置良
## Kafka消息是采用Pull模式还是Push模式
kafka遵循了一种大部分消息系统共同的传统的设计producer将消息推送到brokerconsumer从broker拉取消息。同redis的bpop命令类似Kafka有个参数可以让consumer阻塞知道新消息到达可以防止consumer不断在循环中轮询。
kafka遵循了一种大部分消息系统共同的传统的设计producer将消息推送(push)到brokerconsumer从broker拉取(pull)消息。同redis的bpop命令类似Kafka有个参数可以让consumer阻塞知道新消息到达可以防止consumer不断在循环中轮询。
## kafka中如何防止消息丢失
@ -45,9 +45,11 @@ Kafka消息发送有两种方式同步sync和异步async默认
- 0
表示producer不等待来自broker同步完成的确认继续发送下一条消息
- 1
表示producer在leader已成功收到的数据并得到确认后发送下一条message默认状态
- -1
表示producer在header,follower副本确认接收到数据后才算一次发送完成
@ -107,23 +109,21 @@ Kafka 副本当前分为领导者副本和追随者副本。只有 Leader 副本
message delivery semantic 也就是消息传递语义。通用的概念,也就是消息传递过程中消息传递的保证性。分为三种:
- 最多一次at most once
消息可能丢失也可能被处理,但最多只会被处理一次。
- **最多一次at most once**
可能丢失 不会重复
消息可能丢失也可能被处理,但最多只会被处理一次。可能丢失,不会重复。
- 至少一次at least once
**只管发送,不管对方收没收到。**
消息不会丢失,但可能被处理多次。
- **至少一次at least once**
可能重复 不会丢失
消息不会丢失,但可能被处理多次。可能重复 不会丢失
- 精确传递一次exactly once
**发送之后,会等待对方确认之后才会停止发送。**
消息被处理且只会被处理一次。
- **精确传递一次exactly once**
不丢失 不重复 就一次
消息被处理且只会被处理一次。不丢失,不重复,就一次。
## 介绍一下beanstalk?

@ -630,6 +630,26 @@
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#epoll" class="md-nav__link">
Epoll模式
</a>
<nav class="md-nav" aria-label="Epoll模式">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#epoll_1" class="md-nav__link">
Epoll支持的两种操作模式
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
@ -1841,6 +1861,26 @@
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#epoll" class="md-nav__link">
Epoll模式
</a>
<nav class="md-nav" aria-label="Epoll模式">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#epoll_1" class="md-nav__link">
Epoll支持的两种操作模式
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
@ -1972,14 +2012,19 @@ $ dd if=/dev/urandom of=sync.txt bs=64M count=16 iflag=fullblock oflag=sync
<p>补充:地址空间就是一个非负整数地址的有序集合。如{0,1,2...}。</p>
<h3 id="12">1.2 进程上下文切换(进程切换)</h3>
<p>为了控制进程的执行内核必须有能力挂起正在CPU上运行的进程并恢复以前挂起的某个进程的执行。这种行为被称为进程切换也叫调度。因此可以说任何进程都是在操作系统内核的支持下运行的是与内核紧密相关的。</p>
<p>从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:
1. 保存当前进程A的上下文。</p>
<p>上下文就是内核再次唤醒当前进程时所需要的状态,由一些对象(程序计数器、状态寄存器、用户栈等各种内核数据结构)的值组成。</p>
<p>这些值包括描绘地址空间的页表、包含进程相关信息的进程表、文件表等。
  
2. 切换页全局目录以安装一个新的地址空间。</p>
<p>从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:</p>
<ol>
<li>恢复进程B的上下文。</li>
<li>
<p>保存当前进程A的上下文</p>
<p>上下文就是内核再次唤醒当前进程时所需要的状态,由一些对象(程序计数器、状态寄存器、用户栈等各种内核数据结构)的值组成。</p>
<p>这些值包括描绘地址空间的页表、包含进程相关信息的进程表、文件表等。</p>
</li>
<li>
<p>切换页全局目录以安装一个新的地址空间。</p>
</li>
<li>
<p>恢复进程B的上下文。</p>
</li>
</ol>
<p>可以理解成一个比较耗资源的过程。
  </p>
@ -1998,12 +2043,14 @@ $ dd if=/dev/urandom of=sync.txt bs=64M count=16 iflag=fullblock oflag=sync
<p>对于一次IO访问这回以read举例数据会先被拷贝到操作系统内核的缓冲区中然后才会从操作系统内核的缓冲区拷贝到应用程序的缓冲区最后交给进程。所以说当一个read操作发生时它会经历两个阶段
1. 等待数据准备 (Waiting for the data to be ready)
2. 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)</p>
<p>正式因为这两个阶段linux系统产生了下面五种网络模式的方案
- 阻塞 I/Oblocking IO
- 非阻塞 I/Ononblocking IO
- I/O 多路复用( IO multiplexing
- 信号驱动 I/O signal driven IO
- 异步 I/Oasynchronous IO</p>
<p>正式因为这两个阶段linux系统产生了下面五种网络模式的方案</p>
<ul>
<li>阻塞 I/Oblocking IO</li>
<li>非阻塞 I/Ononblocking IO</li>
<li>I/O 多路复用( IO multiplexing</li>
<li>信号驱动 I/O signal driven IO</li>
<li>异步 I/Oasynchronous IO</li>
</ul>
<h3 id="block-ioio">block I/O模型阻塞I/O</h3>
<p>阻塞I/O模型示意图</p>
<p><img alt="" src="https://static.cyub.vip/images/202012/block-io.png" /></p>
@ -2119,6 +2166,21 @@ $ dd if=/dev/urandom of=sync.txt bs=64M count=16 iflag=fullblock oflag=sync
<p>而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人kernel完成然后他人做完后发信号通知。在此期间用户进程不需要去检查IO操作的状态也不需要主动的去拷贝数据。</p>
</li>
</ul>
<h2 id="epoll">Epoll模式</h2>
<h3 id="epoll_1">Epoll支持的两种操作模式</h3>
<p>epoll对文件描述符有两种操作模式</p>
<ul>
<li>
<p>LTLevel Trigger水平模式</p>
<p>LT是epoll的默认操作模式当epoll_wait函数检测到有事件发生并将通知应用程序而应用程序不一定必须立即进行处理这样epoll_wait函数再次检测到此事件的时候还会通知应用程序直到事件被处理。LT支持阻塞的套接字和非阻塞的套接字。</p>
</li>
<li>
<p>ETEdge Trigger边缘模式</p>
<p>ET模式下只要epoll_wait函数检测到事件发生通知应用程序立即进行处理后续的epoll_wait函数将不再检测此事件。因此ET模式在很大程度上降低了同一个事件被epoll触发的次数因此效率比LT模式高。ET只支持非阻塞的套接字。</p>
</li>
</ul>
<p><strong>ET是状态变化的通知即从没有数据转到有数据会通知LT是数据变化的通知即有数据就通知没数据就不通知</strong>。对于ET模式当接收到通知后应该一直read循环读取直到返回EWOULDBLOCK或EAGAIN这样内部状态才会从有数据再次转为无数据从而为下一次数据的到来做准备否则只有对端再次发送数据时候才会再次触发可读事件。</p>
<p>对于ET状态应该注意防止恶意请求连接防止其一直请求造成其他请求饿死。</p>
<h2 id="_3">资料</h2>
<ul>
<li><a href="https://blog.csdn.net/tjiyu/article/details/52959418">5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO</a>

@ -1131,6 +1131,61 @@
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#redis_3" class="md-nav__link">
基于Redis实现分布式锁的几种方案
</a>
<nav class="md-nav" aria-label="基于Redis实现分布式锁的几种方案">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#setnx-expire" class="md-nav__link">
SETNX + EXPIRE
</a>
</li>
<li class="md-nav__item">
<a href="#setnx-value" class="md-nav__link">
SETNX + value值是(系统时间+过期时间)
</a>
</li>
<li class="md-nav__item">
<a href="#luasetnx-expire" class="md-nav__link">
使用Lua脚本(包含SETNX + EXPIRE两条指令)
</a>
</li>
<li class="md-nav__item">
<a href="#setset-ex-px-nx" class="md-nav__link">
SET的扩展命令SET EX PX NX
</a>
</li>
<li class="md-nav__item">
<a href="#redisson" class="md-nav__link">
Redisson
</a>
</li>
<li class="md-nav__item">
<a href="#redlock" class="md-nav__link">
Redlock
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
@ -1761,6 +1816,61 @@
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#redis_3" class="md-nav__link">
基于Redis实现分布式锁的几种方案
</a>
<nav class="md-nav" aria-label="基于Redis实现分布式锁的几种方案">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#setnx-expire" class="md-nav__link">
SETNX + EXPIRE
</a>
</li>
<li class="md-nav__item">
<a href="#setnx-value" class="md-nav__link">
SETNX + value值是(系统时间+过期时间)
</a>
</li>
<li class="md-nav__item">
<a href="#luasetnx-expire" class="md-nav__link">
使用Lua脚本(包含SETNX + EXPIRE两条指令)
</a>
</li>
<li class="md-nav__item">
<a href="#setset-ex-px-nx" class="md-nav__link">
SET的扩展命令SET EX PX NX
</a>
</li>
<li class="md-nav__item">
<a href="#redisson" class="md-nav__link">
Redisson
</a>
</li>
<li class="md-nav__item">
<a href="#redlock" class="md-nav__link">
Redlock
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
@ -1789,12 +1899,14 @@
<h2 id="redis_1">redis架构</h2>
<ul>
<li>纯内存操作</li>
<li>单线程避免了多线程频繁的上小文切换问题</li>
<li>单线程避免了多线程因为同步导致的频繁的上下文切换问题</li>
<li>高效的数据结构</li>
<li>核心是基于非阻塞的IO多路复用</li>
<li>核心是基于非阻塞的IO多路复用(epoll)</li>
</ul>
<h2 id="_1">应用场景</h2>
<p><img alt="" src="https://static.cyub.vip/images/202406/redis-case.jpg" /></p>
<ul>
<li>缓存</li>
<li>队列</li>
<li>排行榜</li>
<li>自动补全</li>
@ -2069,9 +2181,67 @@ rename-command KEYS &quot;&quot;
info commandstats
info keyspace
</code></pre></div></td></tr></table></div>
<h2 id="redis_3">基于Redis实现分布式锁的几种方案</h2>
<p>基于Redis实现分布式锁的缺点</p>
<ol>
<li>
<p>超时时间不好设置</p>
<p>当线程A获取到锁之后可能业务还没有执行完成锁就过期了</p>
</li>
<li>
<p>锁可能无法永远无法释放</p>
</li>
<li>
<p>锁可靠性问题</p>
<ol>
<li>
<p>对于redis cluster集群当线程A刚获取到锁后此时锁所在Master节点恰好挂了数据还没同步到Slave节点而Slave节点恰好升级为主节点导致B线程可以获取到锁。此时A、B线程同时在执行业务</p>
</li>
<li>
<p>线程A执行完成任务后去释放锁可能是否释放掉了其他线程持有的锁比如线程A执行完成时候锁早已过期线程B获取到了锁</p>
</li>
</ol>
</li>
</ol>
<h3 id="setnx-expire">SETNX + EXPIRE</h3>
<p>如果执行完setnx加锁正要执行expire设置过期时间时进程crash或redis挂掉了会到锁永远无法释放。</p>
<h3 id="setnx-value">SETNX + value值是(系统时间+过期时间)</h3>
<p>可以把过期时间放到setnx的value值里面。如果加锁成功再拿出value值校验一下是否过期即可。</p>
<h3 id="luasetnx-expire">使用Lua脚本(包含SETNX + EXPIRE两条指令)</h3>
<h3 id="setset-ex-px-nx">SET的扩展命令SET EX PX NX</h3>
<blockquote>
<p>SET key value[EX seconds][PX milliseconds][NX|XX]</p>
</blockquote>
<ul>
<li>NX :表示key不存在的时候才能set成功也即保证只有第一个客户端请求才能获得锁而其他客户端请求只能等其释放锁才能获取。</li>
<li>EX seconds :设定key的过期时间时间单位是秒。</li>
<li>PX milliseconds: 设定key的过期时间单位为毫秒</li>
<li>XX: 仅当key存在时设置值</li>
</ul>
<p>XX可以设置当前线程关联的值当要释放锁时候判断当前所锁的关联的值是否是当前线程关联的值如果是才允许释放这解决了3.b问题。可以通过Lua脚本保证这个过程的原子性</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="kr">if</span> <span class="n">redis</span><span class="p">.</span><span class="n">call</span><span class="p">(</span><span class="s1">&#39;get&#39;</span><span class="p">,</span><span class="n">KEYS</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">==</span> <span class="n">ARGV</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="kr">then</span>
<span class="kr">return</span> <span class="n">redis</span><span class="p">.</span><span class="n">call</span><span class="p">(</span><span class="s1">&#39;del&#39;</span><span class="p">,</span><span class="n">KEYS</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="kr">else</span>
<span class="kr">return</span> <span class="mi">0</span>
<span class="kr">end</span><span class="p">;</span>
</code></pre></div></td></tr></table></div>
<h3 id="redisson">Redisson</h3>
<p>给获得锁的线程开启一个定时守护线程每隔一段时间检查锁是否还存在存在则对锁的过期时间延长防止锁过期提前释放。这解决了问题1。</p>
<p>当前开源框架Redisson解决了这个问题。Redisson底层原理如下</p>
<p><img alt="" src="https://static.cyub.vip/images/202406/redisson.webp" /></p>
<h3 id="redlock">Redlock</h3>
<p>对于3.a问题Redis作者 antirez提出一种高级的分布式锁算法Redlock。Redlock核心思想如下</p>
<blockquote>
<p>当一个客户端要获取红锁时,它会尝试在多个 Redis 节点上分别执行 SETNXSET if Not eXists命令如果大多数N/2+1加锁成功了则认为获取锁成功。</p>
</blockquote>
<h2 id="_9">资料</h2>
<ul>
<li><a href="https://blog.csdn.net/zhangpower1993/article/details/89034941">Redis---持久化方式RDB、AOF</a></li>
<li><a href="https://juejin.cn/post/6936956908007850014">七种方案探讨Redis分布式锁的正确使用姿势</a></li>
</ul>

@ -1815,7 +1815,7 @@
<h2 id="hash">一致性Hash算法</h2>
<p>一致性Hash算法是为了解决传统Hash算法比如取余运算时候由于添加或删删除节点时候导致过多数据进行迁移问题而引入的新算法。</p>
<p>假定有几台Redis服务器假定是N要存储key-value数据传统模式是根据hash(key)%N服务器数量来定位出来存放在第几台服务器上面。</p>
<p>一致性Hash算法会使用2<sup>32个虚拟hash槽位可以想象成在一个圆环也叫hash环上面有0到2</sup>32-1编号的槽位。首先我们确定每台Redis服务器在这个环上槽位可以用服务器IP或ID或者name进行hash</p>
<p>一致性Hash算法会使用2^32个虚拟hash槽位可以想象成在一个圆环也叫hash环上面有0到2^32-1编号的槽位。首先我们确定每台Redis服务器在这个环上槽位可以用服务器IP或ID或者name进行hash</p>
<blockquote>
<p>槽位 = hash(Redis服务器IP)%2^32</p>
</blockquote>
@ -1848,7 +1848,7 @@
</li>
</ul>
<h2 id="raft">什么是Raft算法</h2>
<p>Raft算法属于强一致性算法实现。在Raft中每个节点在同一时刻只能处于以下三种状态之一</p>
<p>Raft算法属于最终一致性致性算法实现。在Raft中每个节点在同一时刻只能处于以下三种状态之一</p>
<ul>
<li>领导者(Leader)</li>
<li>候选者(Candidate)</li>
@ -1980,13 +1980,13 @@ cancel 回滚资源操作这个地方的cancel与TCC中的cancel不一样
</ul>
<p><img alt="" src="https://static.cyub.vip/images/202103/service_mesh_api_gateway.png" /></p>
<h2 id="consul">Consul架构是怎么样的</h2>
<p><img alt="" src="https://learn.hashicorp.com/assets/images/consul-arch.png?ynotemdtimestamp=1627634261331" /></p>
<p><img alt="" src="https://static.cyub.vip/images/202406/consul-arch.png" /></p>
<ul>
<li>
<p>Agent是Consul集群中的守护进程。它的生命周期从启动Consul agent开始。Agent可以以client或是server模式运行</p>
</li>
<li>
<p>ClientClient是转发所有RPC请求Server的Agent。Client相对来说是无状态的它的唯一后台活动是参与LAN gossip pool。它的资源开销很小只消耗少量的网络带宽</p>
<p>ClientClient是转发所有RPC请求Server的Agent。Client相对来说是无状态的它的唯一后台活动是参与LAN gossip pool。它的资源开销很小只消耗少量的网络带宽</p>
</li>
<li>
<p>ServerServer是负责参与Raft quorum维护集群状态响应RPC查询和其他datacenter交换WAN gossip信息并转发查询到leader或是远程datacenter的Agent</p>

@ -1636,6 +1636,13 @@
mysql中悲观锁、乐观锁、共享锁、排他锁有什么区别
</a>
</li>
<li class="md-nav__item">
<a href="#_9" class="md-nav__link">
更多资料
</a>
</li>
</ul>
@ -2304,6 +2311,13 @@
mysql中悲观锁、乐观锁、共享锁、排他锁有什么区别
</a>
</li>
<li class="md-nav__item">
<a href="#_9" class="md-nav__link">
更多资料
</a>
</li>
</ul>
@ -2650,33 +2664,40 @@ InnoDB MVCC的实现基于undo log通过回滚指针来构建需要的版本
<h3 id="slow-log">slow log</h3>
<p>slow log用来记录慢查询</p>
<h2 id="wherejionlimitgroup-byhaving">查询语句不同元素where、jion、limit、group by、having等等执行先后顺序</h2>
<p>where字句在聚合前先筛选记录也就是说作用在group by和having字句前。而 having子句在聚合后对组记录进行筛选。</p>
<p>where在聚合前先筛选记录也就是说作用在group by和having前。而 having子句在聚合后对组记录进行筛选。</p>
<h2 id="innodb_1">Innodb为什么一定需要一个主键且必须自增列作为主键</h2>
<p>如果我们定义了主键(PRIMARY KEY)那么InnoDB会选择主键作为聚集索引。如果没有显式定义主键则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引。如果也没有这样的唯一索引则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增这个ROWID不像ORACLE的ROWID那样可引用是隐含的)。</p>
<p>总之Innodb一定需要一个主键。</p>
<ol>
<li>这是因为数据记录本身被存于主索引一颗B+Tree的叶子节点上这就要求同一个叶子节点内大小为一个内存页或磁盘页的各条数据记录按主键顺序存放</li>
<li>如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页这样的页称为叶子页)</li>
<li>如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页(这样的页称为叶子页)</li>
<li>如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新记录都要被插到现有索引页得中间某个位置</li>
</ol>
<h2 id="mvcc_1">在MVCC并发控制中读操作可以分成哪两类?</h2>
<p>快照读 (snapshot read):读取的是记录的可见版本 (有可能是历史版本)不用加锁共享读锁s锁也不加所以不会阻塞其他事务的写</p>
<p>当前读 (current read):读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。</p>
<p><strong>快照读 (snapshot read)</strong>:读取的是记录的可见版本 (有可能是历史版本)不用加锁共享读锁s锁也不加所以不会阻塞其他事务的写</p>
<p><strong>当前读 (current read)</strong>:读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。</p>
<h2 id="mysqldatatimetimestap">Mysql中DATATIME和TIMESTAP的区别</h2>
<p>datetime、timestamp精确度都是秒datetime与时区无关存储的范围广(1001-9999)占空间8个字节timestamp与时区有关查询时候会转换成相应时区显示存储的范围小(1970-2038)占用空间4个字节。</p>
<h2 id="mysql_9">MySQL是如何解决幻读的</h2>
<ul>
<li>事务隔离级别设置为SERIALIZABLE 串行化</li>
<li>
<p>MVCC + Next-Key Lock
Next-Key Lock是Gap Lock间隙锁和Record Lock行锁的结合版都属于Innodb的锁机制。</p>
<p>比如select * from tb where id&gt;100 for update
1. 主键索引 id 会给 id=100 的记录加上 record行锁
2. 索引 id 上会加上 gap 锁,锁住 id(100,+无穷大)这个范围,其他事务对 id&gt;100 范围的记录读和写操作都将被阻塞。插入 id=1000的记录时候会命中索引上加的锁会报出事务异常</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>Next-Key Lock会确定一段范围然后对这个范围加锁保证A在where的条件下读到的数据是一致的因为在where这个范围其他事务根本插不了也删不了数据都被Next-Key Lock锁堵在一边阻塞掉了。
</code></pre></div></td></tr></table></div>
<p>MVCC + Next-Key Lock</p>
<p>Next-Key Lock(临键锁) 是Gap Lock间隙锁和Record Lock记录锁属于行锁的结合版都属于Innodb的锁机制。 比如select * from tb where id&gt;100 for update</p>
<ol>
<li>主键索引 id 会给 id=100 的记录加上 record行锁</li>
<li>
<p>索引 id 上会加上 gap 锁,锁住 id(100,+无穷大)这个范围,其他事务对 id&gt;100 范围的记录读和写操作都将被阻塞。插入 id=1000的记录时候会命中索引上加的锁会报出事务异常</p>
</li>
<li>
<p>Next-Key Lock会确定一段范围然后对这个范围加锁保证A在where的条件下读到的数据是一致的因为在where这个范围其他事务根本插不了也删不了数据都被Next-Key Lock锁堵在一边阻塞掉了。</p>
</li>
</ol>
</li>
</ul>
<blockquote>
<p>记录锁是行级别的锁row-level locks当InnoDB 对索引进行搜索或扫描时,会在索引对应的记录上设置共享或排他的记录锁。</p>
</blockquote>
<h2 id="mysqlgap-locknextkey-lock">Mysql什么时候会取得gap lock或nextkey lock?</h2>
<ul>
<li>只在REPEATABLE READ或以上的隔离级别下的特定操作才会有可能取得gap lock或nextkey lock</li>
@ -2887,22 +2908,24 @@ by other sessions into the gaps covered by the range.</p>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span></pre></div></td><td class="code"><div><pre><span></span><code>idx(a, b, c) HIT where a = x and b = x
idx(a, b, c) HIT where a &gt; x
idx(a, b, c) Not HIT where b &gt; x
idx(a, b, c) Not HIT where a &gt; x and b = x
idx(a, b, c) Not HIT where a = x and c = x
idx(a, b, c) HIT where a = x order by b
idx(a, b, c) HIT where a &gt; x order by a
idx(a, b, c) HIT where a = x and b &gt; x order by a
idx(a, b, c) Not HIT where a &gt; x order by b
idx(a, b, c) HIT where a = x group by a, b
idx(a, b, c) Not HIT where a = x group by b
<span class="normal">12</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="k">Not</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="k">Not</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="k">Not</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="k">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">b</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">a</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">a</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="k">Not</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">b</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">group</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>
<span class="n">idx</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="k">c</span><span class="p">)</span><span class="w"> </span><span class="k">Not</span><span class="w"> </span><span class="n">HIT</span><span class="w"> </span><span class="k">where</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">group</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">b</span>
</code></pre></div></td></tr></table></div>
<p>mysql建立多列索引联合索引有最左前缀的原则即最左优先
- 如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;
- 如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引;</p>
<p>mysql建立多列索引联合索引有最左前缀的原则即最左优先</p>
<ul>
<li>如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引;</li>
<li>如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引;</li>
</ul>
<p>最左前缀索引:</p>
<p>mysql会一直向右匹配直到遇到范围查询(&gt;&lt;、between、like)就停止匹配比如a = 1 and b = 2 and c &gt; 3 and d = 4 如果建立(a,b,c,d)顺序的索引d是用不到索引的如果建立(a,b,d,c)的索引则都可以用到a,b,d的顺序可以任意调整。</p>
<p>如where a&gt;10 order by b ,索引a_b 无法排序
@ -2913,6 +2936,10 @@ idx(a, b, c) Not HIT where a = x group by b
<p><img alt="" src="https://static.cyub.vip/images/202107/mysql-for-update.jpg" /></p>
<h2 id="mysql_15">mysql中悲观锁、乐观锁、共享锁、排他锁有什么区别</h2>
<p><img alt="" src="https://static.cyub.vip/images/202107/mysql-lock.jpg" /></p>
<h2 id="_9">更多资料</h2>
<ul>
<li><a href="https://blog.csdn.net/yzx3105/article/details/129675468">MySQL记录锁、间隙锁、临键锁Next-Key Locks详解</a></li>
</ul>

@ -1791,21 +1791,25 @@
<p>自 Kafka 2.4 之后Kafka 提供了有限度的读写分离也就是说Follower 副本能够对外提供读服务。</p>
<ol>
<li>业务场景不适用。读写分离适用于那种读负载很大,而写操作相对不频繁的场景,可 Kafka 不属于这样的场景。</li>
<li>同步机制。Kafka 采用 PULL 方式实现 Follower 的同步,因此Follower 与 Leader 存 在不一致性窗口。如果允许读 Follower 副本,就势必要处理消息滞后(Lagging)的问题。</li>
<li>同步机制。Kafka 采用 PULL 方式实现 Follower 的同步因此Follower 与 Leader 存 在不一致性窗口。如果允许读 Follower 副本,就势必要处理消息滞后(Lagging)的问题。</li>
</ol>
<h2 id="kafka_3">如何解决kafka消息重复消费问题</h2>
<p>将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。这个解决办法适合其他消息系统。</p>
<h2 id="kafkapullpush">Kafka消息是采用Pull模式还是Push模式</h2>
<p>kafka遵循了一种大部分消息系统共同的传统的设计producer将消息推送到brokerconsumer从broker拉取消息。同redis的bpop命令类似Kafka有个参数可以让consumer阻塞知道新消息到达可以防止consumer不断在循环中轮询。</p>
<p>kafka遵循了一种大部分消息系统共同的传统的设计producer将消息推送(push)到brokerconsumer从broker拉取(pull)消息。同redis的bpop命令类似Kafka有个参数可以让consumer阻塞知道新消息到达可以防止consumer不断在循环中轮询。</p>
<h2 id="kafka_4">kafka中如何防止消息丢失</h2>
<p>Kafka消息发送有两种方式同步sync和异步async默认是同步方式可通过producer.type属性进行配置。Kafka通过配置request.required.acks属性来确认消息的生产</p>
<ul>
<li>
<p>0</p>
<p>表示producer不等待来自broker同步完成的确认继续发送下一条消息
- 1</p>
<p>表示producer在leader已成功收到的数据并得到确认后发送下一条message默认状态
- -1</p>
<p>表示producer不等待来自broker同步完成的确认继续发送下一条消息</p>
</li>
<li>
<p>1</p>
<p>表示producer在leader已成功收到的数据并得到确认后发送下一条message默认状态</p>
</li>
<li>
<p>-1</p>
<p>表示producer在header,follower副本确认接收到数据后才算一次发送完成</p>
</li>
</ul>
@ -1846,19 +1850,18 @@
<p>message delivery semantic 也就是消息传递语义。通用的概念,也就是消息传递过程中消息传递的保证性。分为三种:</p>
<ul>
<li>
<p>最多一次at most once</p>
<p>消息可能丢失也可能被处理,但最多只会被处理一次。</p>
<p>可能丢失 不会重复</p>
<p><strong>最多一次at most once</strong></p>
<p>消息可能丢失也可能被处理,但最多只会被处理一次。可能丢失,不会重复。</p>
<p><strong>只管发送,不管对方收没收到。</strong></p>
</li>
<li>
<p>至少一次at least once</p>
<p>消息不会丢失,但可能被处理多次。</p>
<p>可能重复 不会丢失</p>
<p><strong>至少一次at least once</strong></p>
<p>消息不会丢失,但可能被处理多次。可能重复 不会丢失。</p>
<p><strong>发送之后,会等待对方确认之后才会停止发送。</strong></p>
</li>
<li>
<p>精确传递一次exactly once</p>
<p>消息被处理且只会被处理一次。</p>
<p>不丢失 不重复 就一次</p>
<p><strong>精确传递一次exactly once</strong></p>
<p>消息被处理且只会被处理一次。不丢失,不重复,就一次。</p>
</li>
</ul>
<h2 id="beanstalk">介绍一下beanstalk?</h2>

File diff suppressed because one or more lines are too long

@ -2,207 +2,207 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://docs.cyub.vip/dev-wiki/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/cache/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-network/http/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-network/tcp/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/command/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/compiling-linux-kernel/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/cpu-arch/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/io/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/nptl/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/proc/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/computer-system/systemtap/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/container/cgroup/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/container/image/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/container/install/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/container/namespace/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/container/network/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/elasticsearch/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/elasticsearch/doc_values_and_fielddata/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/elasticsearch/memory/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/elasticsearch/performance_tuning/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/elasticsearch/production_configuring/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/mysql/FAQ/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/mysql/%E4%BA%8B%E5%8A%A1/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/mysql/%E7%AE%80%E4%BB%8B/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/mysql/%E7%B4%A2%E5%BC%95/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/database/redis/redis/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/cache/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/dist/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/docker/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/es/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/go/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/http/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/io/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/mysql/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/nginx/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/protobuf/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/queue/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/redis/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/ref/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/tcp/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://docs.cyub.vip/dev-wiki/qa/%E5%A4%87%E5%BF%98/</loc>
<lastmod>2023-10-11</lastmod>
<lastmod>2024-06-04</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

Binary file not shown.
Loading…
Cancel
Save