开发者学堂课程【高校精品课-上海交通大学-企业级应用体系架构:Caching】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/75/detail/15833
Caching (二)
内容介绍:
一、Memcached
二、MemCached - Storage Commands
三、MemCached - Memory Management
四、Redis
五、Clusterina
三、MemCached - Memory Management
memcached 里面放的是 vlume,就是对象,对象有大有小,如何充分高效的利用内存,在内存里面把所有的对象分成不同的 chunks,再分成小的放对象的块,有的放88个字节,有分成112字节,有分成114的,以此类推,有比较大的柜子,分成一堆小抽屉,一堆中等抽屉,一堆大抽屉,一堆更大的抽屉,排列在柜子里,放戒指或者耳环的小东西,找最小的柜给塞进去,当要放一本书或者是一个手机,一个相机的时候,就找比较大的柜子塞进去,比如放枕头,放被子,找个更大的地方塞进去,总是在找能放得下东西的最小的柜子,找最贴近的放,最节约内存,memcached 就是这个道理,放 person 类对象的时候,要看一个 person 要多少个字节,比如有100个字节,会找到比100个大的最小的 chunks,比如112个字节,在 chunks 里找空位,把东西扔进去,从处理规则可以看到使用内存的方式非常节约。
memcached 在部署时可以有多个节点,可以起三个节点,端口号不一样,或者在三台机器上跑,有一个数据设置tokyo,塞进节点里面的哪个一个才能把它读出来,这件事情不需要 memcached 自己进行处理,memcached 三个节点彼此之间不需要做任何的通信,三个彼此可以独立的存在,找到 tokyo 存放的地址取决于客户端的程序,memcached 可以提供算法,只要用算法就可以,memcached 要求客户端在启动的时候,要配当前有多少台服务器,所以可以看到只配了一个,在11211端口上,提供算法库里面选算法,比如在三个节点之间做 hash,把存到哪个节点,服务器三个之间不需要通信,选中一种算法告诉有多少个节点,拿着键做 hash 就得到应该在哪个上面存,所以在获取 tokyo 对象的时候,只要算法没变,仍然是在列表上做 hash 就能在节点上找到数据,所以在集群里面可以看到,memcached 采用一种比较简单的方式,但是效率比较高,节点之间不需要通信,一个数据一定会存在节点当中的某一个上,服务器端自己通过 hash 确定位置在哪里,不需要控制节点,所有的请求必须转发给控制节点,控制节点再决定后台到哪里拿,把位置变得透明,让客户端直接说清楚服务器有哪一些,方法可以看到 memcached 的实现比较简单,比较灵活,效率比较高,但是有致命缺陷,如果在运行过程中,节点崩了,算法正好在 node1,拿不到就要自己维护,而且需要把列表重新更新,再完全靠客户端的程序,看将来数据应该往哪里更合适,如果有管理节点在屏蔽事情,到底有多少个节点,以及用什么算法完全靠管理节点屏蔽,客户端只把 P 交给管理节点,让它决定到哪里存储,避免节点直接被客户端给看到,直接对客户端产生影响问题,但是一旦这样做 memcached 管理节点就会变得非常重要,有可能成为系统的瓶颈,本来大量的客户端直接就算出在哪里,直接访问三点节点,现在要把大量的客户端的请求全部发到管理节点,管理节点再处理它就有可能成为瓶颈,而且还可能成为单一故障节点,所以基于考虑memcached 不要它,这也是设计的原则,需要节点是屏蔽后台的差异化,还是消除系统当中单一故障节点,即使是崩的节点,另外两个节点上的数据也能用,哪方式好,需要做权衡。
如果数据在进行存储中内存不够,需要增加节点,在 hash 有三个节点,除以三得到余数,余数是零一二,三个当中的一个,三个节点存储节点的标志是零一二,把的键拿出来,累加以后除以三得到结果,就知道在三个节点里哪一个,但是如果内存不够,增加一个,如果除以四类,之前已经存储的节点就找不到,为了避免这样的情况,memcached 用一致性 hash 算法,算法也被称为 chord,节点不光是数据,节点本身也参与到 hash 算法里,所有的数据以及节点都给不同的 id,用 hash 算完之后就是零,比如用四个字节的数值表示数据的 id,算完之后就会有零到二的32次方减一个空位,取值范围在范围内,针对每一个节点,大于零小于第一个节点的 hash 值对应的数据存到节点上,把所有的节点,所有的数据的 hash 值排序,大于节点的 hash 值小于节点的 hash 值的时候,把两个数据存到节点上,所有的数据都存在大于它最小的节点的上面,hash 值大于自身的 hash 值,所有的节点里面最小的,比节点大的有三个节点,但是存储存离的最近的大的节点,存储节点和数据一起在参与 hash,整个四个字节在存储所有的数据,所以最多是零到32次方减一,再往外就溢出,所以最后可以看到像环一样,溢出回到零。
当增加节点的时候,当放到第五个节点,只要把 node5的数据存在 node4节点上,当插入一个节点,计算它的hash,hash 值比新插入的节点小的一部分数据,从原节点上删除,存到新的节点上就可以,只移动几个数据,其它的数据都不动,保证原存储的位置不动,发现增加一个节点不会带来太大的麻烦,原来的节点上面存储的那些数据不受任何影响,原来在哪找,还是在哪找,只有一部分数据发生变化,做修改的时候,查找的时候,大部分的数据是不动的,也不会受影响,小部分的数据要挪动一下,但是查找的算法不动,还是在找比节点最小的,比数据 hash 值大的最小的节点,可以看到使用 hash 可以任意的添加新节点,节点数量增加,有一部分数据会发生变化,后续新加的数据也不受影响,可以随意的增加节点数量。移出节点,节点浪费,所有的内存都没有被利用,把原来的数据挪到的下一个存储节点上就可以删掉,增加和删除都变得非常简单,于是两个东西和前面的客户端通过 hash 的方式确定数据存储的位置,一起组合使用,会发现 memcached 的实践方式非常的灵活,就是想要的的东西,一致性 hash,算法里面有,在很多地方都会利用,存储节点和所有的单个的数据全部参与 hash 计算,得到固定长度,可以是四个字节,也可以是16个字节,看数据的量,固定长度的hash值,因为 hash 是固定长度,所以0是2的32次方,在节点上就是0是2的32次方,溢出了,所以在环里,于是有数据存储分布的协议。