版权声明:本文由韩伟原创文章,转载请注明出处:
文章原文连接:https://www.qcloud.com/community/article/167数据库
来源:腾云阁 https://www.qcloud.com/community缓存
在分布式程序架构中,若是咱们须要整个体系有更高的稳定性,可以对进程容灾或者动态扩容提供支持,那么最难解决的问题,就是每一个进程中的内存状态。由于进程一旦毁灭,内存中的状态会消失,这就很难不影响提供的服务。因此咱们须要一种方法,让进程的内存状态,不太影响总体服务,甚至最好能变成“无状态”的服务。固然“状态”若是不写入磁盘,始终仍是须要某些进程来承载的。在如今流行的WEB开发模式中,不少人会使用PHP+Memcached+MySQL这种模型,在这里,PHP就是无状态的,由于状态都是放在Memcached里面。这种作法对于PHP来讲,是能够随时动态的毁灭或者新建,可是Memcached进程就要保证稳定才行;并且Memcached做为一个额外的进程,和它通讯自己也会消耗更多的延迟时间。所以咱们须要一种更灵活和通用的进程状态保存方案,咱们把这种任务叫作“分布式缓存”的策略。咱们但愿进程在读取数据的时候,能有最高的性能,最好能和在堆内存中读写相似,又但愿这些缓存数据,能被放在多个进程内,以分布式的形态提供高吞吐的服务,其中最关键的问题,就是缓存数据的同步。
服务器
PHP经常使用Memached作缓存网络
为了解决这个问题,咱们须要先一步步来分解这个问题:架构
首先,咱们的缓存应该是某种特定形式的对象,而不该该是任意类型的变量。由于咱们须要对这些缓存进行标准化的管理,尽管C++语言提供了运算重载,咱们能够对“=”号的写变量操做进行从新定义,可是如今基本已经没有人推荐去作这样的事。而咱们手头就有最多见的一种模型,适合缓存这种概念的使用,它就是——哈希表。全部的哈希表(或者是Map接口),都是把数据的存放,分为key和value两个部分,咱们能够把想要缓存的数据,做为value存放到“表”当中,同时咱们也能够用key把对应的数据取出来,而“表”对象就表明了缓存。分布式
其次咱们须要让这个“表”能在多个进程中都存在。若是每一个进程中的数据都毫无关联,那问题其实就很是简单,可是若是咱们可能从A进程把数据写入缓存,而后在B进程把数据读取出来,那么就比较复杂了。咱们的“表”要有能把数据在A、B两个进程间同步的能力。所以咱们通常会用三种策略:租约清理、租约转发、修改广播性能
租约清理,通常是指,咱们把存放某个key的缓存的进程,称为持有这个key的数据的“租约”,这个租约要登记到一个全部进程都能访问到的地方,好比是ZooKeeper集群进程。那么在读、写发生的时候,若是本进程没有对应的缓存,就先去查询一下对应的租约,若是被其余进程持有,则通知对方“清理”,所谓“清理”,每每是指删除用来读的数据,回写用来写的数据到数据库等持久化设备,等清理完成后,在进行正常的读写操做,这些操做可能会从新在新的进程上创建缓存。这种策略在缓存命中率比较高的状况下,性能是最好的,由于通常无需查询租约状况,就能够直接操做;但若是缓存命中率低,那么就会出现缓存反复在不一样进程间“移动”,会严重下降系统的处理性能。spa
租约转发。一样,咱们把存放某个KEY的缓存的进程,称为持有这个KEY数据的“租约”,同时也要登记到集群的共享数据进程中。和上面租约清理不一样的地方在于,若是发现持有租约的进程不是本次操做的进程,就会把整个数据的读、写请求,都经过网络“转发”个持有租约的进程,而后等待他的操做结果返回。这种作法因为每次操做都须要查询租约,因此性能会稍微低一些;但若是缓存命中率不高,这种作法能把缓存的操做分担到多个进程上,并且也无需清理缓存,这比租约清理的策略适应性更好。对象
修改广播。上面两种策略,都须要维护一份缓存数据的租约,可是自己对于租约的操做,就是一种比较耗费性能的事情。因此有时候能够采用一些更简单,但可能承受一些不一致性的策略:对于读操做,每一个节点的读都创建缓存,每次读都判断是否超过预设的读冷却时间x,超过则清理缓存从持久化重建;对于写操做,么个节点上都判断是否超过预设的写冷却时间y,超过则展开清理操做。清理操做也分两种,若是数据量小就广播修改数据;若是数据量大就广播清理通知回写到持久化中。这样虽然可能会有必定的不一致风险,可是若是数据不是那种要求过高的,并且缓存命中率又能比较有保障的话(好比根据KEY来进行一致性哈希访问缓存进程),那么真正由于写操做广播不及时,致使数据不一致的状况仍是会比较少的。这种策略实现起来很是简单,无需一个中心节点进程维护数据租约,也无需复杂的判断逻辑进行同步,只要有广播的能力,加上对于写操做的一些配置,就能实现高效的缓存服务。因此“修改广播”策略是在大多数须要实时同步,但数据一致性要求不高的领域最多见的手段。著名的DNS系统的缓存就是接近这种策略:咱们要修改某个域名对应的IP,并非马上在全球全部的DNS服务器上生效,而是须要必定时间广播修改给其余服务区。而咱们每一个DSN服务器,都具有了大量的其余域名的缓存数据。接口
在高性能的服务器架构中,经常使用的缓存和分布两种策略,每每是结合到一块儿使用的。虽然这两种策略,都有无数种不一样的表现形式,成为各类各样的技术流派,可是只有清楚的理解这些技术的原理,而且和实际的业务场景结合起来,才能真正的作出知足应用要求的高性能架构。