引言
上篇主要是介绍了一些存储相关的知识,还有通过cdn和存储网关进行加速的简单表述。本篇将对存储网关的结构,读算法及相关算法进行分析整理。
CSG的结构
这里只附上CSG结构的两张图,还是要展示一下它的结构的,不然说介绍云存储网关完全不说他也不合适…
可以从结构中看出:
1)在云网关中实现了ISCSI协议,上篇提到过,该协议支持用IP而不是光纤实现SAN存储结构,是网关和服务器剥离的前提。
2)很多结构都是完成本地数据与云存储的契合度优化,提高了存储速度,并发性,稳定性,云网还能更像是本地和云的一种适配器,加速器和优化器。
3)对部署和配置的优化使CSG服务大大减少了在本地搭建SAN的时间和人力成本。
本篇将对结构中的读算法进行简单分析(主讲人就只介绍了读的优化…)
CSG的读优化
传统的数据读方法
1)FIFO
其实这些方法的精髓都能从名字中体会出来。FIFO即First in first out,先进先出原则,数据存储采用队列结构,当数据队列满了的时候,新访问的数据插入队尾,数据在队列中顺序移动,淘汰队首的数据。其中没有任何的其他逻辑,也就是说无论一个信息有多高的访问频率,或者多高的访问量,都最多只存在于队列size的周期,之后要重新入队,这就会对命中率造成影响,虽然实现简单,但是效果不好。
2)LFU
Least Frequently Used 通过频率淘汰数据,核心思想是如果数据过去被访问多次,那么将来也会有较高的访问频率。实现方式是加入了引用计数。虽然查阅资料中大部分描述的是队列,但是看起来更适合用栈结构来实现。新加入数据插入到列尾(引用计数为1)当数据被访问时引用计数增加对列进行重新排序,当需要淘汰数据的时候将列排序在最后的数据删除。首先可以看出这个算法实现上比较复杂,而且每次都要改变计数并重新排列开销较大,再有就是新进来的数据比较容易被淘汰掉,因为起始的计数较小,要看实际的淘汰周期合理性。优点是确实能保证较高的命中率。
3)LRU
Least Recently Used 通过访问时间淘汰数据。核心思想是如果最近被访问过,那么在之后可能会被频繁访问。该算法通过链表来实现,新数据插入到链表的表头,当缓存命中则将命中的缓存移到链表的头部,当链表满的时候,淘汰链表尾部的数据。相比于LFU实现起来更简单,也能保证较高的命中率,但是老数据依然容易被“冲掉”,所以命中率可能不如LFU。
其实比较这几个方法的时候直接说谁好谁坏是不科学的,这些算法都是最简单的模型,如果其中的阈值选的好,更符合实际数据的模型,就能保证更好的命中率,提高存储的读写速度。
CSG的读算法
如图所示,其实ppt里面已经讲的很清楚了,该算法是LRU的一个变种,把整个队列分成冷热两部分。顾名思义热队列维护了比较长驻的信息,冷队列则是一些新的数据。首先,相比于普通的LRU,它能使已存储的较为常用的信息更不容易被替代。
简单来梳理一下几个关键的信息,这个算法关键点一个是m:n的这个比例,会决定算法的效果。还有就是在热存储队列部分,前k%的信息被再次访问时是不会前移的,减少了可能最频繁调用信息触发的重新排序的开销。非k%部分则会放置到hot队列队首。另外cold队列晋升到hot队列也需要check时间间隔,大于1s才会放置到hot队列头部,这个是为了避免短期的多次访问使数据成为“常驻”,只有在一定时间后仍被访问才可能是持久数据,另外短期多次访问该信息也还没有被淘汰掉,不用着急变换位置。所以其实可以看出,hot队列的元素数量变化只和cold队列1s以上重复调用有关,所以分界线偏移也不会很频繁。综上所述,该模型具有一定的合理性,全局的顺序变化又不频繁,大大减少了开销。所以作为一种不停访问的数据结构还是很有参考意义的。
HashTable锁优化
最后我们来讨论一下演讲人在hashTable上的优化,针对这一点其实我是有些疑惑的。要讨论这一点我们先引入三个简单的概念:HashMap,HashTable和ConcurrentHashMap。大部分人都用过或者了解这三个结构。我之前的code也习惯于创建Map的时候直接创建HashMap,好像已经成为了默认的创建模式。比较三者的不同,首先前两个,HashMap不是线程安全的而HashTable是,后两者都是线程安全的,但是支持的锁的级别不一样。HashTable是全表锁,而ConcurrentHashMap是Hash单元锁,是针对Hash表键的锁,所以力度更细,并发起来有更高的效率。再有就是出错处理,ConcurrentHashMap用到的是若一迭代器,也就是说当出现同事写的情况的时候不是简单抛出ConcurrentModificationException,而是在改变的时候创建新的数据而不改变原来的,修改之后再进行替换。提高了性能。再有就是我了解到在使用Hash表的时候有两个常用参数:初始容量和加载因子,之前使用的都是默认的构造器(初始容量是十一,加载因子是0.75)初始容量是hash表的初始大小,比如初始容量是5,那么都一个单元对应0,5…;第二个对应1,6…;第三个对应2,7…以此类推【5(n-1)+i】i={0,1,2,3,4}然后加载因子是什么时候Hash表需要翻倍,这个契机是当Hash表种元素大于现有容量乘以加载因子,就扩大为原来容量的一倍。这些是一些针对Hash表知识的回顾。
回到这次分享,他提到CSG使用了HashTable+桶锁,将原来的全局锁变成了“桶”级别的锁,我觉得应该和ConcurrentHashMap没有什么区别吧,还是有什么更细粒度的check,从他的分享中没有领悟到…
总结
这次的两篇文章其实和云网关没什么太大关系,虽然我也准备了一些时间,但是也说不出来很专业性的内容,大部分都是对之前未掌握的知识和不了解的东西的一些查缺补漏。总的来说是积累了一些本应知道的东西。还有就是针对这次QCon大会,其实我觉得,从我的角度而言,我觉得也可以代表一小部分刚刚从事这个行业不久的人的感受,就是从这个大会中能够得到的,第一个是对新东西的开拓。比如很多分享都是针对互联网黑产,机器学习应用之类。都好像是敲门砖,让自己能看到原来他们的一个处理问题的思路是这样的,这个东西的应用场景是这样的之类。第二点是对一些很多人觉得熟识的而自己还陌生的知识的提醒,分享之后回顾的时候,能够重新把这些知识回顾一下。反正就是虽然收到的干货不多,但是还是很有成长的。最后感谢东方海外给我这个机会去见识外面的世界~