在 kafka 的介绍中看到因为顺序读写磁盘所以很快, 那么请问在 Python 中如何实现顺序读写磁盘?还是说 Python 本身就是顺序读写磁盘的,如果用'a'追加模式打开文件

2021-03-16 19:29:48 +08:00
 smallpython
3820 次点击
所在节点    Python
22 条回复
ruandao
2021-03-16 19:42:24 +08:00
不是因为零拷贝所以比较快吗?
lusi1990
2021-03-16 19:49:06 +08:00
HDD 顺序读写 比 乱序读写 快
jim9606
2021-03-16 23:15:33 +08:00
如果你没用 os.lseek,那基本就是顺序读写,具体是不是顺序读写还要看文件是不是顺序分布在磁盘上,但这是文件系统管的事,python 管不着这个。
ch2
2021-03-16 23:43:32 +08:00
你往一个打开的文件里 write 大量的数据,操作系统就会以顺序的方式写进磁盘
如果你开了一堆不同的文件,这个写一点那个写一点,大概率就是乱序写
搞个前端的项目,npm install 一下几十万个文件,然后再把 node_module 移动到回收站,你就能观察到什么叫乱序读写
xupefei
2021-03-16 23:46:54 +08:00
顺序还是乱序是系统底层的事,面向用户的是一个抽象层,不再有顺序乱序的概念。
不过有一句话是可以说的:如果不断追加写入同一个文件,那这个文件在磁盘里是一整块的可能性比较高。
BBCCBB
2021-03-17 08:45:15 +08:00
比如机械盘, 就是不要让他重复去寻址, 写完继续在当前地址继续写..
lewis89
2021-03-17 09:06:09 +08:00
一般是预申请磁盘空间,这样文件驱动系统分配会连续
wakzz
2021-03-17 09:06:56 +08:00
1. 同一个文件从头都到尾
2. 该文件物理磁盘位置顺序,即写的时候是先申请大块存储空间,然后再在申请的空白空间上写文件,防止文件碎片的问题
3. 该文件不修改或少修改,避免文件碎片
wakzz
2021-03-17 09:10:09 +08:00
@ruandao 零拷贝看上去高大上,其实效果远不如物理文件顺序读写,IO 读写才是性能损耗大头,数据内核拷贝的消耗相对来说就是个零头
smallpython
2021-03-17 09:17:32 +08:00
@jim9606 这就是我疑惑的点, 我也觉得默认就是顺序读写的, 但是如果是这样的话 kafka 单独拿这个出来吹嘘就感觉很奇怪了, 可能还是得深入了解一下他到底是什么意思
xxxyh
2021-03-17 09:32:10 +08:00
kafka 只有追加写的场景,肯定是顺序写,又不是 mysql,还有中间插入一条记录和修改某条记录的需求
4kingRAS
2021-03-17 09:41:27 +08:00
计算机的原理都是相似的,可以看看 malloc 的算法。为了减少 “找 /切换” 的开销,就会用 “池 /预分配” 的方法。
passerbytiny
2021-03-17 09:51:18 +08:00
印象中,kafka 只用很小的篇幅介绍了“顺序读写的 HDD 也很快”,然后花了大量的篇幅去介绍它是如何做到顺序读写的。
cheng6563
2021-03-17 09:58:49 +08:00
一些支持数据库都是写一点数据就写一点日志的,写完日志又回去标记下数据,这样就不顺序了。
xx6412223
2021-03-17 10:20:26 +08:00
@smallpython kafka 的快主要是工作的流程上。client 和分区一一对应,无锁,无随机读,无数据预处理。直接将一个文件的字节一段段传输给 client 。
draymonder
2021-03-17 10:58:46 +08:00
emm,真想知道 kafka 吞吐量

就去看 kafka 的 paper 以及 io 的原理 https://strikefreedom.top/linux-io-and-zero-copy
swulling
2021-03-17 12:51:36 +08:00
@smallpython 人家也没有吹嘘。

顺序读写你直接 append 是无法保证顺序的,kafka 是通过预创建 segment 文件才能保证顺序,每个文件大小默认应该是 1G 。另外读取用的 MMAP 才能保证零拷贝读取,这里面有很多工程细节,远不如你想的那么简单。
abersheeran
2021-03-17 13:06:28 +08:00
任何语言,不 seek 只用 write 都是会保持写入顺序的,但是实际落盘的扇区不一定连续。扇区不连续就意味着读的时候磁头还会做无意义的移动,而不是很顺畅的从头划到尾就行了。

你可以试试用 Python 在一块垃圾机械磁盘上不停 write,效率还是不错的,我在公司发给我的垃圾电脑上试过。

另外,如果你使用过 Windows,那么应该记得 Windows 有一个系统功能就是整理碎片。这个碎片就是指扇区的分布太散,文件读写的时候会慢。
GrayXu
2021-03-17 13:06:53 +08:00
@smallpython 这里的 default 只是说选择吧,不是说这个设计是 naive 的。。
mepwang
2021-03-17 13:58:22 +08:00
这和操作系统的 IO 缓存机制有关
由于 IO 操作比 CPU 和内存操作慢数个数量级,在进行磁盘 IO 时,操作系统不会一次只读取一个或几个字节,而是一次性读取一大块数据(比如每次 IO 都会读取 64K )。要是顺序读取的话,需要的数据大概率落在一个数据块中,实际发生的 IO 操作只有一次,因此就表现的比较快。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/762238

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX