深入浅出jcr之十二 key-value存储系统

简介:
      在写文章方面,惰性心理无时无刻不折磨着我,文章的标题已经列在那里很长时间,可是我就是不愿意打开,不愿意把心中所想描绘出来。类似的情况可能也折磨着很多的其他同学。虽然jackrabbit是一个小众的框架,看的人和想看的人非常的少,但是其中确实包含了很多值得我们学习和研究的技术和实现,当然也有很多不足,需要我们去改进。所以我强迫自己继续写下去。

上一篇文章讲到高亮和及时搜索的问题,在文章的最后我也提出了一些问题,就是如果将高亮去掉,那么势必会带来一个问题,那就是小文本文件的存储问题,一般有大型网络经验的人都知道,小文本存储在磁盘上,读取性能是非常低的,原因就是当前的磁盘的构造决定的。

当前市面的磁盘由磁头和磁片组成,数据都通过磁头写到磁片上,而写在磁片上又是根据磁道来划分,如果我们的小文件是单独存储的,那么一个磁头会将它们写在不同的磁道上,下次在读取的时候,磁头就需要不停的寻道,找到它想读取到的文件。寻道有两个过程,第一个是找到正确的磁道,而第二个过程是找到磁道上正确的起始位置。尤其是第一过程,寻道过程在大并发的情况下,磁头需要不停的进行寻道的工作,这个寻道是非常的消耗时间的。
所以小文件存储讲究的合并,即将小文件合并成大文件。

同样,在jackrabbit中,由于二进制文档数据被提取之后,是放到索引文件的,所以带来的一个问题是索引文件的大小成倍增加,在索引同步的时候,代价明显增大,这一点ahuaxuan在前文中也有较为相信的描述。而现在,我们就是要解决这个问题,提取之后的文本数据究竟应该放在什么地方。

是单独放在目录里面吗?对目录进行分级,一般多个大文件,比如视频文件之类的都会采取这种做法。对于一个平均长度是100kb-200kb的文本数据来说,如果也采取目录分级的方法来存放的话,那势必会存在非常多的这种文件,一旦又涉及到集群,那么对于jackrabbit来说,这一定是一场噩梦。

最好的方法是能够将这些小文件存储到一个大文件中,而且可以通过nodeid直接取到这样的小文本。这个时候我们就自然而然的想到使用key-value数据存储系统。比如市面上有tc,bdb,等等,但是他们都是local的,还是做不了数据的共享,无法使用到集群的场景下,一个clustorNode的数据无法和其他clustorNode共享。

这个时候我们又自然而然的想到memcachedb, tt+tc, mina+bdb.通过在local的key-value存储系统上套一个socket服务,一个local的key-value存储系统变成了一个remote的key-value系统,任何人都可以调用它们的服务。即使是在集群的环境下,也没有问题了。

大的方向确定之后,就是做各种性能测试。第一个排除的是memcachedb,之前有人跟我讲它的性能不是很好,我还不相信,经过自己的一轮测试下来,发现,在100kb文本的情况下,50000次save操作,耗时超过了我吃饭的时间。调整参数之后再测,稍微快一点,但是还是太慢了,有空整理一下我的测试结果。

为了确保bdb没有这么差的性能,我开始测试java版本的bdb在100k文本下的性能,经过多次测试,在我这块7000转的磁盘上,每秒钟的写入速度可以达到23m/s,读取速度38m/s,每秒钟读取100kb文本可以到350requests/second,这证明bdb是没有问题的。

那么memcachedb不够快应该是其本身的问题(当然也不排除我的参数配置不准确,即使不准确,也不应该差这么多)。

于是,我自定义了一个简单二进制协议,用mina+bdb,实现java版本的memcachedb,同样的测试,结果为写入14m/s,读取17m/s,每秒平均请求数为150 requests/s.

显然,这里有很大的优化的余地。至少网络io上不应该成为瓶颈。而且可以大胆的预测,在真正的存储系统中,磁盘将会是主要性能瓶颈。支持多磁盘的key-value存储系统可以有效的提高系统的整体读写性能。

同样我也测试过tc+tt,50000次100kb的save,耗时1300秒,在大文本的情况下性能也不咋滴。而且它还不支持多磁盘。更正,上面的结果是受网络环境的限制。我的测试网络带宽一会4m,一会20m,晕倒,等会把测试代码放到tc+tt server上测试

同时也希望使用过memcachedb存储大文本的同学出来说说它的性能到底如何。
目录
相关文章
|
Java 关系型数据库 MySQL
maven项目中添加MySql依赖失败(以及maven的安装到maven项目的使用过程)
maven项目中添加MySql依赖失败(以及maven的安装到maven项目的使用过程)
4060 1
maven项目中添加MySql依赖失败(以及maven的安装到maven项目的使用过程)
|
存储 SQL API
SqlAlchemy 2.0 中文文档(二十四)(4)
SqlAlchemy 2.0 中文文档(二十四)
239 0
|
前端开发 JavaScript 安全
跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
|
Linux
Linux系统之dstat命令的基本使用
`dstat`命令的灵活性和多样性使其成为监测系统性能的有用工具,可以根据需求选择显示不同的统计信息。
211 1
Linux系统之dstat命令的基本使用
|
前端开发 开发者 Ruby
Sass、LESS区别是什么?大家为什么要使用他们?
Sass(Syntactically Awesome Style Sheets)和LESS(Leaner CSS)是两种流行的CSS预处理器,它们在原生CSS的基础上提供了一些额外的功能和语法。
542 1
|
资源调度 前端开发 JavaScript
Vite教程 安装
Vite教程 安装
1673 0
Vite教程 安装
|
存储 缓存 NoSQL
黑马点评笔记 redis实现缓存
黑马点评笔记 redis实现缓存
311 0
|
JSON 物联网 开发工具
设备接入组件功能介绍
设备接入组件功能介绍
649 0
|
安全 网络协议 网络安全
网络安全体系之分层防护
作为全方位的、整体的网络安全防范体系也是分层次的,不同层次反映了不同的安全问题,根据网络的应用现状情况和网络的结构,将安全防范体系的层次划分为物理层安全、系统层安全、网络层安全、应用层安全和安全管理。
770 0
|
JSON JavaScript 前端开发
如何使用depcheck检查vue和react的依赖,以后不用把时间浪费在依赖问题上了
当我们在开发 JavaScript 项目时,会引入各种依赖库。但是有些依赖库可能只用到了部分功能,或者已经不再需要了,但是却一直被保留在项目中。