disk queue 简介
disk queue是基于文件存储的FIFO(first-in-first-out)队列。在对数据进行持久化的同时,保证数据写入和读出的相对顺序。
在NSQ中,disk queue的应用场景为:
- 生产者在生产消息时,当消息内存缓冲区已经满了的时候,则利用disk queue将消息存储在文件系统中。
- 消费者在进行消费时,如果内存缓冲区的数据已经被消费完,则利用disk queue来消费存储在文件系统中的消息。
disk queue 实现方法
首先说明一下disk queue用于数据读写的几个变量:
- readFileNum : 表示当前应该从readFileNum这个序号的文件中读取数据。
- readPos : 表示当前应该从readFileNum这个序号的文件的readPos位置开始读取数据。
- writePosNum : 表示当前应该向writeFile这个序号的文件中写入数据。
- writePos : 表示当前应该从writeFileNum这个序号的文件的writePos位置开始写入数据。
在读取数据时,首先会根据readFileNum和readPos来确定应该从哪个文件的哪个位置开始读取数据;message数据的结构如上图所示,首先要读取4byte长度的数据,作为消息体的长度。在得知消息体长度之后,再读取相应byte的消息体。
在读取一条消息后,readPos和readFileNum指针会根据读取的字节数向后移动,若超出了单个文件的最大长度,那么直接去下一个新的数据文件中读取数据。
同理,写入消息时会根据writeFileNum和writePos来确定应该从哪个文件的哪个位置开始写入数据;确定位置后,先写入4byte数据作为消息长度,再写入消息数据。写完当前消息之后,会向后挪动writePos和writeFileNum指针,同样的,超出单个文件的最大长度后,会在下次写入的时候创建一个新的数据文件,并将消息写入新的文件中。
disk queue 主要结构
1 | // diskQueue implements a filesystem backed FIFO queue |
disk queue 主要方法
diskqueue.go 主要包括了3个主要的方法:readOnce, writeOnce, ioLoop。
readOnce
readOnce方法的作用为从磁盘中读取一条message。
1 |
|
writeOnce
writeOnce方法的作用为向磁盘中写入一条message。
1 | // writeOne performs a low level filesystem write for a single []byte |
ioLoop
在创建diskqueue实例后,ioLoop作为一个goroutine会在后台循环执行,并处理读取、写入等请求。
1 |
|
reference
- disk queue source code : https://github.com/nsqio/go-diskqueue