python 内存文件系统_IO/内存/文件系统

linux io协议栈

005ee54701f480314de7ed7a775e8cda.png

裸设备读写

数据库公认最快的IO方式是读写裸设备,Oracle数据库一般将日志和数据全部存放到裸设备上.

什么是裸设备

在Unix/Linux, 文件分为两个大类:字符设备文件和块设备文件.

裸设备是一种没有经过格式化,不被Unix通过文件系统来读取的特殊块设备文件, 也叫裸分区(原始分区), 通过字符设备驱动读写裸设备

裸设备的优点

裸设备不通过Unix/Linux的文件系统管理, 节省了文件管理的开销; 文件系统作为物理磁盘的抽象, 并且维护这个抽象的一整套逻辑, 是需要一定开销的;

对裸设备的操作不通过系统的缓冲区, 数据在ORACLE的数据缓冲区(BUFFER CACHE)和磁盘间直接传递, 能在一定程度上提高I/O性能, 适合大量IO的场景使用

缺点

容量管理不便, 需要提前规划容量

裸设备的创建和扩展等操作都需要root权限

写日志

写日志是数据库常用的保证可靠性的重要手段之一, 其原因是文件系统本身不可靠, 所以事务需要通过日志来保证一致性. 可以参考崩溃一致性, 在多种情况下, 可认为已经完成文件写入的情况, 发生异常并恢复后会发现并没有写成功.

日志式与非日志式文件系统

日志文件系统会跟踪记录文件变化, 理论上讲同一大小的文件, 日志文件系统占用的空间会稍大一些, 但文件日志提供了快速恢复等功能.

对于非日志型文件系统, 当进行一个写操作时,操作系统首先修改文件系统的元数据(metadata),然后再写入实际数据。

如果元数据正在被修改时, 发生系统崩溃或机器掉电, 文件系统就有可能被损坏. 日志型文件系统比非日志文件系统会多出一个专门写日志的日志区, 可根据需要选择先写日志或先写数据.

多数日志型文件系统支持三种日志方式,分别是回写、顺序、全日志, 默认是顺序模式, 即先写数据后写日志.

Linux的ext2/ext3/ext4均为日志型文件系统. Windows的NTFS也是日志型文件系统.

日志算法

WAL: Write-Ahead Logging, 预写日志系统, HBase和MySQL都使用WAL, 具体流程为

修改记录前,一定要先写日志;

事务提交过程中,一定要保证日志先落盘,才能算事务提交完成。

通过WAL方式,在保证事务特性的情况下,可以提高数据库的性能。

缓冲IO/非缓冲IO/直接IO

缓冲/非缓冲IO

Linix对IO文件的操作分为不带缓存的IO操作(文件IO)和带缓冲的IO(标准IO).

标准IO符合ANSI C的标准, 不依赖系统内核, 可移植性强, 能减少对read和write的系统调用次数, 读写文件时会在用户层建立一个缓冲区.

不带缓存的IO, 并不是直接对磁盘操作, 只是用户层没有缓存, 在内核仍然是缓存的(系统调用).操作系统会将IO数据缓存在文件系统的页缓存(page cache)中.

两者的区别在于, 不带缓存的IO每次写入时都会写入磁盘, 而标准IO是有缓冲区的, 缓冲区满或者程序flush/close时, 才会写入磁盘; 最终都会调用无缓冲的C标准I/O库函数, 包括open 、read 、write 、close 等系统函数

标准IO调用malloc来分配缓存, 有三种类型:

全缓存: 当填满标准I/O缓存后才执行I/O操作. 磁盘上的文件通常是全缓存的

行缓存: 当输入输出遇到新行符或缓存满时, 才由标准I/O库执行实际I/O, 常见的Stdin/Stdout通常是行缓存

无缓存: 相当于read/write调用. stderr通常是无缓存的,因为必须尽快输出

Stdin/Stdout默认是全缓冲,但在终端中是行缓冲。linux中行缓冲的大小是1k,全缓冲的大小是4k. 由于linux的lazy机制, 只有当实际进行输入/输出时才会分配缓冲区.

缓存I/O,在一定程度上分离了内核和用户空间, 保护了系统的运行安全; 可以减少读盘的次数, 从而提高性能.不过另一方面, DMA将数据从磁盘读到页缓存或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,多次拷贝时会有较大的cpu及内存开销.

数据流向:

无缓存IO: 数据-> 内核缓存区-> 磁盘

标准IO: 数据-> 流缓存区-> 内核缓存区-> 磁盘

CIO/DIO

CIO/DIO技术一般用于数据库中, 如裸设备读写.

DIO即direct IO. DIO直接与硬盘交互, 直接将磁盘数据读到用户空间的缓冲区或用户空间的内存直接写入磁盘,不使用内核的缓存而使用用户自己的缓存.

88d7e09392ec06f7c6656c706d97c32a.png

CIO即Concurrent IO, 当某个文件被多个进程同时访问时, 就出现了Inode竞争的问题, 读操作使用的共享锁, 多个读操作可以并发进行, 而写操作使用排他锁. 当锁被写进程占用时, 其他所有操作均阻塞, 此时整个应用的性能将会大大降低。

当文件系统支持CIO并开启CIO时, CIO默认会开启文件系统的DIO,进行数据存储的时候不会经过数据buffer, 而且会串行执行. 因此在文件系统层面无需考虑数据一致性.

CIO的实现依赖于底层的driver

待续

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "io/ioutil" 是一个 Python 标准库,用于读取文件内容。它提供了一种简单的方式来读取文件中的数据,并返回一个字节字符串。该函数接受一个文件名作为参数,并返回一个包含文件内容的字节字符串。例如: ``` import io with io.open('file.txt', 'r', encoding='utf-8') as f: content = f.read() ``` 以上代码将打开名为 "file.txt" 的文件,并将其内容读入变量 "content" 中。在这个例子中,文件使用 UTF-8 编码。注意,使用 "with" 语句可以保证在读取完文件后,文件会被自动关闭。 ### 回答2: "io/ioutil" 是Go语言的一个标准库包,提供了对文件和目录的简单的读写操作函数。 这个包的名字是由三个部分组成的,"io"代表输入输出操作,"util"代表实用工具,而"io/ioutil"则是具体的一个工具集合。 "io/ioutil"包中的函数具有简洁易用的特点,使用这个包可以更方便地进行文件读写操作。其中最常用的函数是"ioutil.ReadFile"和"ioutil.WriteFile"。 "ioutil.ReadFile"函数用于读取文件中的全部内容,并将内容以字节切片的形式返回。例如: ``` content, err := ioutil.ReadFile("example.txt") if err != nil { fmt.Println("读取文件失败:", err) } else { fmt.Println("文件内容:", string(content)) } ``` "ioutil.WriteFile"函数用于将指定的字节切片内容写入文件,并可指定文件的权限。例如: ``` data := []byte("Hello, world!") err := ioutil.WriteFile("example.txt", data, 0644) if err != nil { fmt.Println("写入文件失败:", err) } else { fmt.Println("文件写入成功") } ``` 除了这两个函数外,"io/ioutil"包还提供了其他一些函数,例如"ioutil.TempDir"用于创建临时目录,"ioutil.TempFile"用于创建临时文件等。这些函数都是为了提供更方便的文件和目录操作而设计的,减少了开发者的重复劳动。 总之,"io/ioutil"是一个非常实用的Go语言标准库包,提供了简单易用的文件和目录操作函数,极大地方便了开发者的文件处理工作。 ### 回答3: "io/ioutil" 是Go语言中的一个包(package),它提供了一些用于处理文件输入输出的工具函数。 首先,"io/ioutil" 提供了一种简便的方式用于读取文件内容。通过使用 ioutil.ReadFile() 函数,我们可以以二进制或者文本的形式直接读取整个文件的内容到内存中。这个函数会自动管理文件的打开和关闭操作,简化了文件读取的过程。 其次,"io/ioutil" 还提供了一些简单的函数用于实现文件的写入。比如 ioutil.WriteFile() 函数可以将一个字节切片或者字符串写入文件,同样也会自动处理文件打开和关闭。 此外,还有一些对于文件和目录进行操作的函数。比如 ioutil.ReadDir() 可以读取一个目录下的所有文件和子目录的信息,并以一个文件切片的形式返回。另外,ioutil.TempFile() 函数可以创建一个临时文件,以便在程序执行过程中临时存储数据。 总之,"io/ioutil" 包提供了一些方便的工具函数,帮助我们更简单地进行文件的读写操作。无论是读取文件内容,还是写入文件数据,都可以通过这个包实现,简化了我们处理文件的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值