存储系统实现-构建自己的存储系统(一)

        一直在断断续续的看Lucene源码,怎么也理不清其中千丝万缕的联系,遂想自己边写边理解。在写的过程中更加理解索引的意义,以及在开发过程中如何利用索引加快检索,如何利用跳跃表来实现快速查找。如何利用缓存来实现减少磁盘IO的开销。

         这里先从整个流程说起,这里简单的模拟了一下数据存储和查找的过程。在写这个的过程中基本可以深刻理解索引的真实意义。

         存储数据

1.      在数据文件中写入数据,得到该数据的起始位置和结束位置,也就是两个偏移量。目前我存储这三个值每个对象也就20个字节,即使5万的索引数据也就1M,这样的数据在内存中直接操作都没有问题。

2.      在索引文件中生成一个主键,然后把数据文件中得到的两个偏移量存储到索引文件中。

查询数据(按主键ID查找)

1.      在索引文件中根据主键ID查找相应的偏移量。这里如果是从头开始遍历性能还是比较差的。我在文件中如果存储了100万的数据,如果获取最后一条数据需要的时间是7~10秒,这样的性能是不可接受的。因为整个存储是顺序存储(按ID自增),所以可能会想到二分查找。我这里使用了跳跃表的查找方式。如果按照一般的步长的话读第100万条数据需要走100万步,那么如果用跳跃表的方式可以大大简少读取和数据的对比次数。优化后单线程的性能在100毫秒以内。性能还是相当不错。后续会专门开辟一篇文章来讲我的实现方式。

2.      根据这个偏移量去数据文件去查找相应的数据。

问题

1.             我这里是直接存储数据的偏移量来直接定位数据,这样会有一个非常严重的问题,就是在数据更新的时候会破坏整个数据的偏移量,所以看似这种用存储偏移量可以极快的加快检索速度,但是如果有插入和更新操作中性能损失是致命的,这意味着需要更新整个存储的偏移量。目前还在探索中,还没有想到一个比较好的解决办法来解决!

2.             缓存的使用,因为不管是读还是写文件的过程中都是需要加锁的。所以在并发的过程中会导致锁等待,这样性能会有比较大的损失。我这里使用了内存缓存缓存一些热点数据,命中率比较高的情况下性能还是有比较大的提升,由于整个内存比较有限,所以希望最大限度的缓存索引,以达到减少IO开销的目的。如果是随机访问的话性能会比较差,所以如何提高随机访问的性能也是我后续需要思考的问题。

总结

通过写这个存储,可以学习一些比较底层的知识。后续不断完善中。

你可能感兴趣的:(存储系统)