自己动手写数据库:缓存管理的设计

数据库系统设计中一个必须关注的瓶颈就是读写效率。由于数据库系统要处理高吞吐量的数据读写,由于数据量大,系统不能总是把所有数据都存储在内存中,但是频繁的操作磁盘就会导致系统效率大大降低,因此我们必须要有办法权衡数据在内存和磁盘上的存储, 我们要让数据尽可能多的从内存进行读写,尽可能少的触发磁盘操作,因此设计一个有效的缓存管理系统对效率有致命的作用。

我们本节要设计一个缓存管理器,它会预先分配固定数量的内存页,也就是我们前面几节实现的Page对象,由此形成一个内存池,当其他组件想要读写数据时,他们先通过缓存管理器获得内存页,然后必须在给定协议的基础上与缓存管理器进行交互,这样才能确保后者有效的保证数据的准确性和读写的效率性,这里有几个要点需要说明:

1, 如果一个缓存页被分配给其他组件进行读写,那么这个缓存页就会处于一个状态叫"pinned",意思就是有个钉子把这个页面给钉住了。只要一个缓存页处于"pinned"状态,缓存管理器就不能对其进行回收。

2,如果缓存页使用完毕,使用它的客户必须对它进行"unpin",这点就像c++中内存分配的new和delete,如果不unpin就会导致可用缓存遗失。

3.当某个组件向缓存管理器申请缓存页面读取某个二进制文件对应的区块时,可能会有两种情况发送,一种情况是要读取的数据已经存储在某个页面里,这样缓存管理器就会设置这个页面为pinned状态,然后将页面提交给客户,等客户完成使用后让管理器对该页面执行unpin操作,这里需要注意的是,一个已经被pin过的页面可以再次被pin,这意味着同一个缓存页面有多高客户在读取,管理器会对页面设置一个pin计数,当页面被pin时计数加1,被unpin时计数减1,当计数为0时说明该页面没有再被使用,可以分配给其他数据。

第二种情况是数据还没有读入缓存,同时管理器还有空闲的内存页面可以使用,这样管理器将数据读入空闲页面,然后将页面提交给客户。

第三种情况是数据没有读入内存,但是管理器已经没有空闲页面可用,此时客户可能就得等待。

这里需要注意的还有,当多个客户在使用同一个内存页面时,他们都可以根据自己的需要读写页面,缓存管理器不在乎数据的一致性,这些需要我们在后面实现的并发管理器来保证。为了保证效率,当一个页面被客户使用完后,如果里面数据有修改,管理器也不会直接将数据写入磁盘,如果接下来有其他客户同样需要读写相同的区块数据,那么管理器会直接将页面提交给客户,于是第二个客户的读写有可能会覆盖第一个客户的读写数据,只有在合适的时机管理器才会将页面数据写入磁盘,这个我们后面会解释。

如果客户要读取的数据还没有读入某个缓存页面,那么管理器会执行的操作如下:首先它会选择一个处于unpin状态的页面,这里又有两种情况需要考虑,首先是这个页面原先读取了其他区块的数据,而且这些数据被其他客户进行了修改,那么管理器必须要先将该页面的数据写入对应的文件区块,然后才能将新区块的数据写入该页面;如果这个页面的数据只读但没有被写入,那么管理器就能直接将所需区块的数据写入该页面。

为了实现缓存管理器,我们需要实现一个Buffer对象,它实际上是在我们前面实现的Page基础上再增加一些管理计数功能,例如一个页面被pin的次数,并负责将计数为0的page重新放入缓存池等。同时Buffer对象也负责Page针对磁盘的写入,当一个缓存页使用计数为0时,Buffer会根据策略延迟将其数据写入磁盘,因为这个页面的数据在后面可能又被其他客户或组件需要,那么Buffer会直接将这个页面提交给客户,于是客户就能直接读取已经被修改后的数据。<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值