kafka
包含
Producer。
Broker:具体的服务器
Consumer(Group)、
Kafka使用ZooKeeper对集群元数据进行持久化存储,如果ZooKeeper丢失了Kafka数据,集群的副本映射关系以及topic等配置信息都会丢失,最终导致Kafka集群不再正常工作,造成数据丢失的后果。
2.topics和partitions
在kafka的配置文件$KAFKA_HOME/config/server.properties中有记录日志删除策略;对于consumer来pull消息不需要锁机制
kafka默认使用端口9092
#这三项都配置
broker.id=1
delete.topic.enable=true
或者用listener
host.name=172.16.84.21
num.network.threads=16
num.io.threads=48
background.threads=24
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
min.insync.replicas=2
#在可用性和消息丢失之间做出权衡
unclean.leader.election.enable=false
group.max.session.timeout.ms=3600000
auto.create.topics.enable=true
queued.max.requests=5000
connections.max.idle.ms=600000
#It will migrate any partitions the server is the leader for to other replicas prior to shutting down
controlled.shutdown.enable=true
#ISR踢出策略,默认10000ms,参数在官文中可查
#消费者只能看到已经复制到ISR的消息
replica.lag.time.max.ms = 10000
controlled.shutdown.max.retries=3
controlled.shutdown.retry.backoff.ms=5000
controller.socket.timeout.ms=30000
#单个消息被压缩后的最大值,默认1M(1000 000)
#这个值对性能有显著的影响
#消费者客户端设置fetch.max.bytes的必须与服务器端设置的消息
#大小进行协调
message.max.bytes=2000000
fetch.max.bytes=
replica.fetch.max.bytes=2500000
auto.leader.rebalance.enable=true
leader.imbalance.check.interval.seconds=120
num.replica.fetchers=8
log.roll.hours=168
log.segment.delete.delay.ms=60000
###########消息存放的目录,这个目录可以配置为“,”逗号分割的表达式
log.dirs=/data/kafka/kafka-logs
##########新建Topic的默认Partition数量#################
num.partitions=1
default.replication.factor=3
log.cleaner.threads=8
num.recovery.threads.per.data.dir=8
##############日志删除策略##########################
#每个主题可以设置单独的保留策略
log.retention.hours=360
log.retention.bytes=默认1G
##################################################
acks=all
buffer.memory=
compression.type=
retries=
batch.size=
client.id=
linger.ms
#元数据刷新时间
metadata.max.age.ms
#日志片断(segment)被关闭后,才会计算上面的过期信息
log.segment.bytes=1073741824
log.segment.ms=
log.retention.check.interval.ms=300000
###############Kafka通过Zookeeper管理集群配置,选举leader########################
zookeeper.connect=172.16.84.21:2181,172.16.84.22:2181,172.16.84.23:2181
zookeeper.connection.timeout.ms=6000
zookeeper.session.timeout.ms=6000
zookeeper.sync.time.ms=2000
offsets.retention.minutes=10080
group.initial.rebalance.delay.ms=3
max.in.flight.requests.per.connection=5
3.Producer消息路由
不同的消息可以并行写入不同broker的不同Partition里,极大地提高了吞吐率
4.启动
#先启动zookeeper集群
export ZOOKEEPER_HOME=/usr/local/zookeeper-3.4.11
bin/zkServer.sh start [conf/zoo0.cfg]
#启动命令
export KAFKA_HOME=/usr/local/kafka_2.12-1.0.0
bin/kafka-server-start.sh [-daemon] config/server.properties
zkCli.sh
get /brokers/topics/__consumer_offsets/partitions/40/state
#查看kafka版本
ll libs/kafka*.jar
5.常用命令
此时消费者可接收到消息,但是顺序和生产者的发送顺序不一样,也就是说当一个主题有多个分区时,消费者接受消息的顺序是乱序的,因为每个partition的网络性能不一样,读写性能也不一样。
重置消费组offsets时,该组应该不是正在消费
Assignments can only be reset if the group 'console-consumer-16754' is inactive
##列出消费组
myIP=$(ip -4 addr show eth0 | awk -F'[ /]+' '/inet/ { print $3 }')
kafkaServer=${myIP}:9092
kafka-consumer-groups.sh --bootstrap-server $kafkaServer --list
#重置offsets
kafka-consumer-groups.sh --bootstrap-server $kafkaServer --group console-consumer-16754 --topic s2 --execute --reset-offsets --to-earliest
#模拟消费
kafka-console-consumer.sh --bootstrap-server $kafkaServer --group console-consumer-16754 --topic s2
#当提示group选项不可用时
bin/kafka-console-consumer.sh --bootstrap-server $kafkaServer --topic s2 --consumer-property group.id=1 --from-beginning
#或者
--consumer.config config.file
#################################
#这些脚本都是调用kafka-run-class.sh,以一个对应的类名为参数,来启动一个java进程
# 列出某一消费者组对其topic的消费情况
group=euip-securities-access
./kafka-consumer-groups.sh --bootstrap-server $kafkaServer --describe --group $group | awk '$2=="euip-securities-error" {printf "%s\t%-16s%s\n" ,$3,$6,$8}'
./kafka-consumer-groups.sh --bootstrap-server $kafkaServer --describe --group $group | awk '$2=="euip-securities-access" {sum+=$6} END {print sum}'
0.8以前的kafka,消费的进度(offset)是写在zk中的,所以consumer需要知道zk的地址。后来的版本都统一由broker管理,所以就用bootstrap-server了。
连接多台只是保证其中一台挂了,producer还能连接上kafka集群,producer生产的消息还是会以消息指定的分区或者key或者轮询或者随机的存在kafka集群的某个节点上
zk的leader和kafka的controller不是同一个
# 查看topic信息
./kafka-topics.sh --describe --zookeeper localhost:2181
# 生产者 , //my-kafka-topic时topic的名字
kafka-console-producer.sh --broker-list localhost:9092 --topic my-kafka-topic
6.问题
kafka-consumer-groups.sh --bootstrap-server 2.2.11.79:9092 --describe --group g1
Consumer group 'g1' is rebalancing
可能是参数问题,使用em的配置后,再使用生产、消费、重置命令是正常的 2021-04-18 在笔记本中用单台虚拟机搭建zk和kafka集群,也没有办公机上的3台卡
7.
要启用幂等性,只需将 Producer的参数中 的参数中 的参数中 enable.idempotence设置为 设置为 true即可
8. 生产者分区
按指定partition,有key value ,无key来分别存储,数据实际存储的位置是在logs.dir下的topic-partition
分区数的选择:
如果你估算出主题的吞吐量和悄费者吞吐量,可以用主题吞吐量除以消费者吞吐量算出分区的个数。也就是说, 如果每秒钟要从主题上写入和读取lGB 的数据,并且每个消费者每秒钟可以处理50MB的数据,那么至少需要20 个分区。这样就可以让20 个消费者同时读取这些分区,从而达到每秒钟lGB 的吞吐量。
如果不知道这些信息,那么根据经验,把分区的大小限制在25GB 以内可以得到比较理想 的效果。
在日志片段被关闭之前消息是不会过期的
磁盘性能影响生产者,而内存影响消费者。不建议把Kafka 同其他重要的应用程序部署 在一起的原因,它们需要共享页面缓存,最终会降低Kafka 消费者的性能。
使用集群最大的好处是可以跨服务器进行负载均衡,再则就是可以使用复制功能来避免因单点故 障造成的数据丢失
9.操作系统调优
9.1 虚拟内存
#建议把vm.swappiness 参数的值设置得小一点,比如1
/proc/sys/vm/swappiness
/proc/sys/vm/dirty_background_ratio //小于10
/proc/sys/vm/dirty_ratio //60-80比较合理
#为了给这些参数设置合适的值,最好是在Kafka 集群运行期间检查脏页的数量
grep -E 'dirty|writeback' /proc/vmstat
9.2 磁盘
文件元数据包含3 个时间戳: 创建时间( ctime )、最后修改时间( mtime)以及最后访问时间( atime)。默认情况下,每次文件被读取后都会更新atime ,这会导致大量的磁盘写操作。Kafka 用不到该属性,所以完全可以把它禁用掉。为挂载点设置noatime 参数可以防止更新atime
修改/etc/fstab,如下
/dev/sdb1 /home/disk0 ext4 defaults 0 2
改成
/dev/sdb1 /home/disk0 ext4 noatime 0 2
修改/etc/fstab设置后需要重新挂载文件系统、不必重启就可以应用新设置。remount分区,执行:
mount -o remount /home/disk0
如果不想改fstab,直接用mount命令:
mount -o noatime,remount /home/disk0
9.3 网络
#socket读写缓冲区,单位byte
net.core.wmem_default
net.core.rmem_default
net.core.wmem_max=2097152
net.core.rmem_max=2097152
#tcp socket的读写缓冲区,这些参数的值由3 个整数组成,它们使用空格分隔,分别
#表示最小值、默认值和最大值
#例如,“4096 65536 2048000”表示最小值是4K、默认值是64K、最大值
#是2MB 。根据Kafka 服务器接收流量的实际情况,可能需要设置更高的最大值
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem
#启用tcp时间窗扩展
net.ipv4.tcp_window_scaling=1
#可以接收更多的并发连接
net.ipv4.tcp_max_syn_backlog //大于1024
#大于1000,有助于应对网络流量的爆发,特别是千兆网络
net.core.netdev_max_backlog
10.消费者
在Kafka 和其他系统之间复制数据时,使用正则表达式的方式订阅多个主题是很常见的做法
消费者往一个叫作_consumer_offset 的特殊主题发送消息,消息里包含每个分区的偏移量
11.
集群里第一个启动的broker 通过在Zookeeper 里创建一个临时节点/controller让自己成为控制器,控制器负责在节点加入或离开集群时进行分区首领选举
Kafka 最为常见的几种请求类型:元数据请求、生产请求和获取请求
主题级别的配置参数是replication.factor,而在broker 级别则可以通过default.replication.factor来配置自动创建的主题。
建议把broker 分布在多个不同的机架上,并使用broker.rack 参数来为每个broker 配置所在机架的名字。如果配置了机架名字, Kafka 会保证分区的副本被分布在多个机架上,从而获得更高的可用性
enable.auto.commit
auto.commit.interval.ms
12. connector
echo '{ "name": "load-kafka-config", "config": { "connector.class": "FileStreamSourceConnector", "file": "config/server.properties", "topic": "kafka-config-topic" } }' | curl -XPOST -d@- http://localhost:8083/connectors --header "content-type:application/json"
#执行这个没有生成新文件
curl -s -X POST -H "Content-Type: application/json" --data '{"name": "dump-kafka-config",
"config":
{"connector.class":"org.apache.kafka.connect.file.FileStreamSinkConnector",
"key.converter.schemas.enable":"true",
"file":"demo-file.txt",
"tasks.max":"1",
"value.converter.schemas.enable":"true",
"name":"file-stream-demo-distributed",
"topics":"kafka-config-topic",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter":"org.apache.kafka.connect.json.JsonConverter"}
}' http://localhost:8083/connectors/
Kafka 是一个分布式的基于发布/订阅模式的消息队列。具有高性能、持久化、多副本备份、横向扩展能力,主要应用场景是:日志收集系统和消息系统。
kafka的特性:
- 同时为发布和订阅提供高吞吐量。
- 可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,
- 分布式系统,易于向外扩展。所有的 Producer、Broker 和Consumer 都会有多个,均为分布式的。并且,无需停机即可扩展机器。
- 消息被处理的状态是在 Consumer 端维护,而不是由 Broker 端维护。当失败时,能自动平衡。
- 同时支持离线数据处理和实时数据处理。
消息队列的模式
-
点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
生产者生产消息发送到Queue中,然后消息消费者从Queue中去除并且消费消息,消息被消费者消费后,Queue中不在存储,所以消费者不可能消费已经被消费到的消息,Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

-
发布/订阅模式(一对多,消费者消费数据之后不会清除消息)
生产者将消息发布到topic中,同事有多个消息消费者消费该消息,和点对点方式不同,发布到topic的消息会 被所有订阅者消费

kafka结构及概念

kafka的大体结构可以分为,消息生产者producer,kafka集群Broker cluster,消息消费者consumer,zookeeper集群
概念:
- producer:消息生产者,向kafka broker发送消息
- consumer:消息消费者,从kafka broker取消息
- consumer group;消息消费者组,有多个consumer组成,消息消费者组内每个消费者负责消费不同的分区数据,一个组内的消费者消费一个分区,消费者组之间互不影响。消费者组是逻辑上的一个订阅者
- broker :一台kafka服务器就是一个broker,一个集群由多个broker组成,broker存储着topic的数据,每个broker只存储着topic的一个partition,
- topic:主题,每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处
- partition: 分区,topic中的数据分为一个或者多个partition,每个top至少有一个partition,每个partition中的数据使用多个segment,每个 partition 是一个有序的队列,不同partition间的数据丢失了数据的顺序。如果topic有多个partition,消费数据时就不能保证数据的顺序
- replica: 副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,
- leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader。
- follwer: 每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower。
kafka安装
待续。。。
工作流程及broker的消息存储


producer写入流程:
producer采用推(push)模式将消息发布到broker,每条消息都被追加(append)到分区(patition)中
1)producer先从zookeeper的 “/brokers/…/state”节点找到该partition的leader
2)producer将消息发送给该leader
3)leader将消息写入本地log
4)followers从leader pull消息,写入本地log后向leader发送ACK
5)leader收到所有ISR中的replication的ACK后,增加HW(high watermark,最后commit 的offset)并向producer发送ACK
Kafka 中消息是以 topic 进行分类的,生产者生产消息,消费者消费消息,都是面向 topic的。topic 是逻辑上的概念,而 partition 是物理上的概念,每个 partition 对应于一个 log 文件,该 log 文件中存储的就是 producer 生产的数据。Producer 生产的数据会被不断追加到该log 文件末端,且每条数据都有自己的 offset。消费者组中的每个消费者,都会实时记录自己消费到了哪个 offset,以便出错恢复时,从上次的位置继续消费。


我们可以看到,每个Partition中的消息都是有序的,生产的消息被不断追加到Partition log上,其中的每一个消息都被赋予了一个唯一的offset值。

由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位效率低下,Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment。每个 segment对应两个文件——“.index”文件和“.log”文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic 名称+分区序号。例如,first 这个 topic 有三个分区,则其对应的文件夹为 first-0,first-1,first-2
00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log
index文件和log文件以当前 segment 的第一条消息的 offset 命名
.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中 message 的物理偏移地址。


存储策略
无论消息是否被消费,kafka都会保留所有消息。有两种策略可以删除旧数据:
1)基于时间:log.retention.hours=168
2)基于大小:log.retention.bytes=1073741824
需要注意的是,因为Kafka读取特定消息的时间复杂度为O(1),即与文件大小无关,所以这里删除过期文件与提高 Kafka 性能无关。
Kafka生产者端
1 分区策略
-
分区原因
- 方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个 topic又可以有多个 Partition 组成,因此整个集群就可以适应任意大小的数据了
- 可以提高并发,因为可以以 Partition 为单位读写了
-
分区有序性
Kafka以分区作为最小的粒度,将每个分区分配给消费者组中不同的而且是唯一的消费者,并确保一个分区只属于一个消费者,即这个消费者就是这个分区的唯一读取线程。那么,只要分区的消息是有序的,消费者处理的消息顺序就有保证。每个主题有多个分区,不同的消费者处理不同的分区,所以Kafka不仅保证了消息的有序性,也做到了消费者的负载均衡。
分区的原则
1)指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
2)未指定patition但指定key,通过对key的value进行hash出一个patition
3)patition和key都未指定,第一次调用时随机生成一个整数(后
面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法。

2 分区可靠性保证
为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果producer 收到 ack,就会进行下一轮的发送,否则重新发送数据。

副本的同步策略:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 半数以上完成同步,就发 送 ack | 延迟低 | 选举新的 leader 时,容忍 n 台节点的故障,需要 2n+1 个副本 |
| 全部完成同步,才发送ack | 选举新的 leader 时,容忍 n 台节点的故障,需要n+1个副本 | 延迟高 |
kafka选择全部完成同步,才发送ack,这样节省资源,但是存在一个问题,:leader 收到数据,所有 follower 都开始同步数据,但有一个 follower,因为某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去,直到它完成同步,才能发送 ack。
解决办法:ISR
leader维护了一个动态的ISR(和 leader 保持同步的 follower 集合)当 ISR 中的 follower 完成数据的同步之后,leader 就会给 follower 发送 ack。如果 follower长时间未向leader同步数据 , 则该follower将被踢出ISR , 该 时 间 阈 值 由replica.lag.time.max.ms参数设定。Leader 发生故障之后,就会从 ISR 中选举新的 leader
ack应答机制:
对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等 ISR 中的 follower 全部接收成功。所以 Kafka 为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,选择以下的配置
| ack | |
|---|---|
| 0 | producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟,broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据 |
| 1 | producer 等待 broker 的 ack,partition 的 leader 落盘成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么将会丢失数据; |
| -1(all) | producer 等待 broker 的 ack,partition 的 leader 和 follower(这里指的是ISR) 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复(follower同步完的时候没发ack,leader挂掉的情况)。 |
将服务器的 ACK 级别设置为-1,可以保证 Producer 到 Server 之间不会丢失数据,但是会重复数据,(At Least Once)相对的将服务器 ACK 级别设置为 0,可以保证生产者每条消息只会被发送一次,不会出现数据重复。(At Most Once )
但是对于重要的数据不能丢失也不能重复,在0.11 版本的 Kafka,引入了一项重大特性:幂等性 Producer 不论向 Server 发送多少次重复数据,Server 端都只会持久化一条。
At Least Once + 幂等性 = Exactly Once
如何实现幂等性:ack=-1 并且将 Producer 的参数中 enable.idempotence 设置为 true
开启幂等性的 Producer 在初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而Broker 端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker 只会持久化一条,但是 PID 重启就会变化,同时不同的 Partition 也具有不同主键,所以幂等性无法保证跨分区跨会话的 Exactly Once。
3 发生故障的处理

HW:
指的是消费者能见到的最大的 offset,ISR 队列中最小的 LEO
LEO:
指的是每个副本最大的 offset
1)follower 故障
follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后,follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该Partition的HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了
2)leader 故障
leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据
注意:这只能保证副本之间的数据一致性(由hw保证),并不能保证数据不丢失或者不重复(由ack控制)。
消费者端
消费方式
消息由生产者发布到Kafka集群后,会被消费者消费。消息的消费模型有两种:推送模型(push)和拉取模型(pull)
Kafka的 consumer 采用 pull(拉)模式从 broker 中读取数据,push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的。它的目标是尽可能以最快速度传递消息,但是这样很容易造成 consumer 来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而 pull 模式则可以根据 consumer 的消费能力以适当的速率消费消息
pull 模式不足之处是,如果 kafka 没有数据,消费者可能会陷入循环中,一直返回空数据。针对这一点,Kafka 的消费者在消费数据时会传入一个时长参数 timeout,如果当前没有数据可供消费,consumer 会等待一段时间之后再返回,这段时长即为 timeout。
分区分配策略
当消费者个数发生变化时触发
一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。Kafka 有两种分配策略,一是 RoundRobin,一是 Range。
-
RoundRobin
按照消费者组分配,将所有主题的分区组成 TopicAndPartition 列表,然后对 TopicAndPartition 列表按照 hashCode 进行排序,分发给每一个消费者,如果两个消费者订阅不同的主题,容易造成消息错乱,因此消费者最好只订阅一个topic

-
Range(默认)
按照单个主题划分,按照消费者总数和分区总数进行整除运算来获得一个跨度,然后将分区按照跨度进行平均分配,以保证分区尽可能均匀地分配给所有的消费者

消费者offset的维护
由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢复后继续消费

Kafka 0.9 版本之前,consumer 默认将 offset 保存在 Zookeeper 中,从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为**__consumer_offsets**
Zookeeper 在kafka中的作用
- 1、Broker 在 ZooKeeper 中的注册。
- 2、Topic 在 ZooKeeper 中的注册。
- 3、Consumer 在 ZooKeeper 中的注册。
- 4、Producer 负载均衡。Producer 从 Zookeeper 拉取 Topic 元数据,从而能够将消息发送负载均衡到对应 Topic 的分区中
- 5、Consumer 负载均衡。
- 6、记录消费进度 Offset 。
- 7、记录 Partition 与 Consumer 的关系。
总结:Broker、Producer、Consumer 和 Zookeeper 的交互。( 1、2、3、5 )
相应的状态存储到 Zookeeper 中。(4,6,7)
kafka 高效读写的原因
- 顺序写磁盘
Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。官网有数据表明,同样的磁盘,顺序写能到 600M/s,而随机写只有 100K/s。这与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。
- 零拷贝技术
零拷贝主要的任务就是避免CPU将数据从一块存储拷贝到另外一块存储,主要就是利用各种零拷贝技术,避免让CPU做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让CPU解脱出来专注于别的任务。这样就可以让系统资源的利用更加有效。
生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。官网有数据表明,同样的磁盘,顺序写能到 600M/s,而随机写只有 100K/s。这与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。

浙公网安备 33010602011771号