Skip to content

Commit bba94d1

Browse files
committed
Redis的模型
1 parent 9169d96 commit bba94d1

3 files changed

Lines changed: 84 additions & 0 deletions

File tree

Interview/sad/MVCC,redolog,undolog,binlog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,18 @@
1515
4. **binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redolog是循环使用**
1616
5. **binlog可以作为恢复数据使用,主从复制搭建****redolog作为异常宕机或者介质故障后的数据恢复使用**
1717

18+
**MVCC的缺点:**
19+
20+
MVCC在大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。缺点是每行记录**都需要额外的存储空间,需要做更多的行维护和检查工作**。 要知道的,MVCC机制下,会在更新前建立undo log,根据各种策略读取时非阻塞就是MVCC,undo log中的行就是MVCC中的多版本。 而undo log这个关键的东西,**记载的内容是串行化的结果,记录了多个事务的过程,不属于多版本共存**。 这么一看,似乎mysql的mvcc也并没有所谓的多版本共存
21+
22+
**读写分离原理**
23+
24+
主库(master)将变更写**binlog**日志,然后从库(slave)连接到主库之后,从库有一个**IO线程**,将主库的binlog日志**拷贝到自己本地**,写入一个中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容,也就是在自己本地再次执行一遍SQL,这样就可以保证自己跟主库的数据是一样的。
25+
26+
这里有一个非常重要的一点,就是从库同步主库数据的过程是**串行化**的,也就是说**主库上并行**的操作,在从库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行SQL的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。
27+
28+
而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。
29+
30+
所以mysql实际上在这一块有两个机制,一个是**半同步复制**,用来解决主库数据丢失问题;一个是**并行复制**,用来解决主从同步延时问题。
31+
32+
所谓并行复制,指的是从库**开启多个线程,并行读取relay log中不同库的日志**,然后并行重放不同库的日志,这是库级别的并行。

Interview/sad/Redis的模型.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
面试官:Redis为什么快?
2+
3+
我:内心:不知道为什么一直问这个问题。
4+
5+
1. 纯内存操作
6+
2. 单线程操作,避免了**频繁的上下文切换**
7+
3. 合理高效的数据结构
8+
4. 采用了**非阻塞I/O多路复用**机制
9+
10+
实际上Redis服务器是一个事件驱动程序,分为**文件事件****时间事件**,就主要讲一下文件事件。
11+
12+
Redis基于Reactor模式开发了自己的网络事件处理器:这个处理器被称为文件事件处理器
13+
14+
- 文件事件处理器使用**I/O多路复用程序来同时监听多个套接字**,并根据套接字目前执行的任务来为套接字**关联不同的事件处理器**
15+
- 当被监听的套接字准备好执行连接**应答、读取、写入、关闭**等操作时,与操作相对于的文件事件就会产生,这时**文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件**
16+
- 简单点:**就是一堆套接字请求,被一个叫做I/O多路复用程序监听,通过文件事件分派器一个一个和事件处理器绑定在一起去处理**
17+
18+
I/O多路复用程序是有常见的select、epoll等系统调用所实现的。有个小故事,自行理解BIO、NIO、select、poll、epoll等
19+
20+
故事情节为:**老李去买火车票,三天后买到一张退票。参演人员(老李,黄牛,售票员,快递员),往返车站耗费1小时。**
21+
22+
**往返车站可以看成系统调用,调用一次一小时**
23+
24+
### 1. 阻塞I/O模型
25+
老李去火车站买票,排队三天买到一张退票。
26+
27+
耗费:在车站吃喝拉撒睡 3天,其他事一件没干。
28+
29+
### 2. 非阻塞I/O模型
30+
老李去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。
31+
32+
耗费:往返车站6次,路上6小时,其他时间做了好多事。
33+
34+
2比1多了个自己轮训调用
35+
36+
### 3. I/O复用模型
37+
1. select/poll
38+
39+
老李去火车站买票,委托黄牛,然后每隔6小时电话**黄牛**询问,黄牛三天内买到票,然后老李去火车站交钱领票。
40+
41+
耗费:往返车站2次,路上2小时,黄牛手续费100元,打电话17次
42+
43+
实际上,就是自己不断调select(像个船一样,装了很多描述符)询问哪些描述符可读可写,比如又一个可读了,咱就调用可读系统调用就ok了
44+
45+
2. epoll
46+
47+
老李去火车站买票,委托黄牛,**黄牛买到后即通知老李去领**,然后老李去火车站交钱领票。
48+
耗费:往返车站2次,路上2小时,黄牛手续费100元,无需打电话
49+
50+
实际上,自己不用管了,当有可读的时候,直接中断你,然后你自己去读
51+
52+
### 4. 信号驱动I/O模型
53+
54+
老李去火车站买票,给售票员留下电话,有票后,售票员电话通知老李,然后老李去火车站交钱领票。
55+
56+
耗费:往返车站2次,路上2小时,免黄牛费100元,无需打电话
57+
58+
不要黄牛了,省了这个单线程,系统通知你,你收到以后自己去读
59+
60+
### 5. 异步I/O模型
61+
老李去火车站,告诉售票员要买票,售票员买到票之后,打电话通知老李把票放在某某储物箱,老李根据储物箱地址自己去取票。
62+
63+
耗费:往返车站1次,路上1小时,免黄牛费100元,无需打电话
64+
65+
只需要注册一次,得到消息之后,就去另外一个地址上取走票
66+
67+
黄牛是多路复用,他不仅可以帮你买票,还可以其他人买票,还可以买飞机票,高铁票等。
68+

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
- [MySQL索引](/Interview/sad/MySQL索引.md)
7979
- [MySQL数据库结构优化](/Interview/sad/MySQL数据库结构优化.md)
8080
- [MySQL的锁](/Interview/sad/MySQL的锁.md)
81+
- [Redis的模型](/Interview/sad/Redis的模型.md)
8182

8283
## 刷题系列
8384
- [推荐:CS-Notes](https://cyc2018.github.io/CS-Notes/#/?id=✏️-算法)

0 commit comments

Comments
 (0)