美文网首页分布式系统
Akka DData分布式数据缓存

Akka DData分布式数据缓存

作者: Queen〇fLaponia | 来源:发表于2019-03-05 11:32 被阅读0次

      Ddata用于在节点间共享数据,我们知道一说到共享麻烦事儿就来了,特别是集群情况下,因为它意味着并行/并发的读和写、不知道什么时候、不知道在什么地方随机发生读或者写。传统RDB数据库没这个烦恼,因为它是单点(分布式存储也需要这么一个单点即主节点),数据访问方法都是串行的。这期间包含两种IO:网络和磁盘的,如果是事务还可能有多次磁盘IO、如果是分布式事务那可能有多次网络/磁盘IO...

      ddata使用键值形式存储和访问数据(所以数据可看做data entry)、值即所谓的Conflict Free Replicated Data Types(CRDT),CRDT基于因果推断允许在任意节点更新数据,而不需要和外部协调,大数据首先就得干掉分布式事务,分布式事务就是需要外部协调的典型,要提高效率,每个节点首先需要是自恰自驱的、自主决策,要crud干就完了,用不着跟谁商量,只要能够merge即可,求同存异、埋头苦干就是效率最高的。CRDT数据结构保障自动merge更新,这些数据结构包括:counters, sets, maps and registers.

      ddata分布式数据和Amazon Dynamo的相似点比较多,目前看CRDT由于需要支持数据merge带来额外负担是肯定的,所以ddata可以用于集群状态同步、但不适用大数据量高并发业务数据。Akka的集群就用ddata同步成员状态,The cluster membership state is a specialized CRDT, which means that it has a monotonic merge function. When concurrent changes occur on different nodes the updates can always be merged and converge to the same end result.

    All data entries are spread to all nodes

      和其他Akka组件如分片套路类似,ddata也是基于actor style来使用的:你可以用Replicator复制器actor访问ddata数据、每台节点机都需要启动这个actor我们把它叫做replica、各个节点机上的replica组成一个分布式数据复制层(类似分片的分布式ShardRegion层)、你的程序在哪个节点机上就和那个节点机上的replica打交道;所有replica都是一样的名字、一样的path.  拿到本机replica actorRef有个便利方法:

        val replicator = DistributedData(context.system).replicator

      写和读数据就是给replicas !Update消息,CRDT基于gossip收敛的,默认一致性保障是保证最终一致性,最终一致的系统,可能读到过期值:a read may return an out-of-date value.  注意只是可能,这还要取决于一致性级别:类似卡珊德拉,Akka分布式数据对每条读写都可以指定一致性级别(代码示例):

    1、WriteLocal写本地:写入本地replica、写方法立即返回、之后disseminated with gossip;

    2、WriteTo(n)写n个:写入值需要写到至少n个replicas去包括本地replica;

    3、WriteMajority写多数:写入值需要写到占集群多数个的replicas去,比如:N/2 + 1个,N是集群节点机数量。WriteMajority配ReadMajority,可以为它们定义最少节点数minCap,这样可以减少/甚至消除读到陈旧数据的风险,minCap定义了多数值Majority,最低是N / 2 + 1.

      对于小集群来说(节点机<7),成员变动可能很容易影响多数值Majority.   此时minCap更有意义。

    4、WriteAll写全部:实时的、同步的、强一致写,集群所有节点全写完、才算写完,此时是CP系统;

      读一样有上述一致性指定。在你本地,你所做的所有写以及读写之间都是有序的、有保障的。写是否成功是通过消息告知你的:Replicator.UpdateSuccess/UpdateFailure,这是异步的,我们知道凡是异步消息其ack需要采用类似correlationID形式做到:In the Update message you can pass an optional request context, which the Replicator does not care about, but is included in the reply messages. This is a convenient way to pass contextual information (e.g. original sender) without having to use ask or maintain local correlation data structures.

    读的结果数据也是通过消息给到你,读写能够在指定timeout内按照指定一致性级别完成则返回成功消息

      归纳来说:

      1、异步消息可以看作同步RPC的超集,用Akka我们可以ask然后同步等待;

      2、基于gossip协议的最终一致架构可以看做强一致的超集;

      上述的前者都可以做到后者的功能(性能需要测试验证),反之不然,这是因为架构约束。最终一致架构也可以支持强一致,反之不然,比如HBase只能强一致,但是Akka/Cassandra都可以灵活支持某条数据的一致性级别:写入/读取一个节点机(最高性能、最终一致)、写入/读取大多数节点机(一致性和性能的均衡)、写入/读取所有节点机(集群范围强一致)。总之,基于Akka可以简便的构建即支持异步消息传输、也支持同步RPC调用的合理系统,比如对于海量流式metric/log数据,以异步传输为主(也可以支持异步ack);对于UI界面查询请求或命令下发,以RPC方式调用。

      小总结一下你为什么选择Akka:Akka实现了Actor模型,并且在此之上提供了诸多价值,首要价值也是Actor模型的主要价值即解耦,actor的解耦是在最深层次的对象级别上的解耦,打破了单体程序的局限,达到真正的高并发的同时使得分布式成了水到渠成,与此技术路线相似的有ErLang、Go语言的goroutine或在其他语言中称之为协程、纤程的技术。Akka不仅仅在运行时提供价值,更重要的可能是对开发也提供了诸多价值:

      1.     对并发模型进行了更高的抽象,使程序员构建并发、并行应用的难度大幅度降低并且统一了二者,基于Akka开发的分布式并行程序,可以在单机调试,之后不改代码只改配置直接部署到多机运行;

      2.     基于scala语言,使代码量显著降低,同时大幅度提升代码的业务描述能力。大幅消减java等传统语言中的模板代码、固定流程代码,可以消除所有业务无关的例行公事的操作代码,实现代码直接表达业务,达到近似DSL的精简业务描述效果;

      3.     与scala语言的面向并发特性良好结合,scala语言与Akka由一家公司统一维护,创始人也是java语言编译器作者,所以在Akka当中结合scala的面向并发编程有明确、全面的最佳实践总结和误区、注意点总结,Akka的一些经过实践检验的优良特性也会合并到scala语言,而scala语言一直在引领java语言的发展方向。另外,所有java生态圈中的工具,scala语言都可以无缝采用,反之不然;

      4.     Akka以库依赖形式使用,可以很方便的结合springBoot。其actor开发模型兼容面向对象,actor既可以有状态也可以有行为,使其业务建模更加自然合理(个人认为这是DDD死灰复燃的唯一机会);可以实现核心业务模块完全无锁、无阻塞,这使得核心业务代码在开发时完全可reason out

      最后,说说微服务,其本质就是SOA2.0,就是新瓶装旧酒,基本属于一波技术泡沫。依据是SOA做得好的微服务就能做好,SOA做不好的微服务也做不好:

      1、SOA ESB做得好,微服务Service Mesh就比较火。这里面唯一变数是服务间交互协议,希望在于RSocket,sm如果紧跟反应式大趋势,做好RSocket支持,尚能峰回路转漂亮转身;

      2、SOA服务注册+编排做的不好,微服务一样做不好;特别是编排,微服务也必将在服务编排上困难重重。而没有了服务编排的服务注册,也叫不响了,类似jmDNS早就有轻量级的局域网服务发现能力,再搞个服务注册中心近乎鸡肋;

    相关文章

      网友评论

        本文标题:Akka DData分布式数据缓存

        本文链接:https://www.haomeiwen.com/subject/ricnuqtx.html