阅读随手记 201704

关键字:微服务, 架构, Elasticsearch, 分布式队列, 搜索引擎, 推荐系统, 机器学习, 人工智能, Java 9, CQRS, Event Source, Kafka, 高可用。

Elasticsearch前沿:ES 5.x改进详解与ES6展望 曾勇

  • 如果你的场景是日志,那么基本上数据进去之后是不需要进行修改的,所以现在ES新增了一个append-only的索引模式,也就是当ES是自动生成ID的时候,ES可以跳过不必要的版本检测,大概可以提升20%左右的索引性能
  • 在数据结构方面,新增了多个range字段类型,现在你可以计算连续数据的交并集,可以是时间范围,也可以是数值范围。
  • 下一个特性值得介绍的就是_all 字段的移除,去掉_all字段之后,磁盘占用少了不少,索引性能也有一些提升。
  • 现在有一个新的高亮器:Unified Highlighter,大家可能会问,目前ES默认已经提供了3种不同的高亮器,为什么还会有一个新的轮子呢,因为之前的用法有点复杂, 用户选择起来比较困难,新的unified highlighter目的就是简化高亮的使用,可以支持前面3种高亮类型的自动选择。
  • 还有一个是keyword类型可以通过normalizer来进行标准化了,keyword类型相比text类型就是不能分词,但是可能同样需要进行相应的标准化处理,比如统一转成小写,移除标点符号等等,使用方式和analyzer一样。
  • 另一个就是Multi-Word Synonyms,之前是不支持同义词中间有空格分割的,分词的时候会帮你切分开,搜索的时候不能正确处理词组这种同义词。
  • 同义词现在可以支持词组了,也就是说同义词如果是由多个词组成的,不会在分词的时候被傻傻的拆开,而是正确的处理。
  • 还一个就是字段折叠( Field collapsing),这个特性比较有意思,你可以在搜索的时候,按某个字段作为维度进行去重,我这里写过一篇详细的博客,有兴趣的可以去看看:http://elasticsearch.cn/article/132
  • ES的搜索,对于一些耗时较长的查询,现在可以通过ES的任务管理机制来进行取消了,感兴趣的可以查看文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search.html#global-search-cancellation
  • 现在term aggs提供了一种分区的概念,你可以对一个字段,分n次进行聚合,分而治之,有兴趣的可以看看文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.3/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions
  • 当你的集群变红的时候,新增的 /_cluster/allocation/explain 接口能够直接告诉你哪里出了问题;
  • Java REST Client也有了更新,ES之前提供了一个偏底层的Java HTTP REST client,但是用起来太费劲,需要手动拼 JSON,现在Java REST Client分成了Java High Level REST Client和Java Low Level REST Client, High Level基于Low Level来实现,顾名思义,提供更多用户方便的接口调用,High Level REST Client将提供和Transport Client类似的接口,不用手动去拼接QueryDSL的JSON了,目测在 5.5 版本提供。
  • 以前的搜索的reduce操作都是要等到把每个分片的结果都拿到本地之后再做合并,现在新增的batched search reduce phases提供了分批进行reduce的行为,也就是不用全部拿到之后再做reduce,而是拿到足够的分配(默认512)之后就开始做reduce,然后拿到合并结果,释放相关的资源。
  • ES 6.0展望:稀疏性Doc Values的支持;Index sorting,即在索引阶段的排序,即我们查询的时候有时候会根据某个字段的值进行排序,比如时间、编号等等;顺序号的支持,每个es的操作都有一个顺序编号,这个属于es内部的一个功能,可以提供快速的分片副本恢复或同步、跨数据中心的节点恢复、甚至提供一个Changes API 等;无缝滚动升级,使之能够从5的最后一个版本滚动升级到6的最后一个版本,不需要集群的完整重启。

Elasticsearch 5.x 字段折叠的使用 medcl

  • 什么是字段折叠,可以理解就是按特定字段进行合并去重,比如我们有一个菜谱搜索,我希望按菜谱的“菜系”字段进行折叠,即返回结果每个菜系都返回一个结果,也就是按菜系去重,我搜索关键字“鱼”,要去返回的结果里面各种菜系都有,有湘菜,有粤菜,有中餐,有西餐,别全是湘菜,就是这个意思,通过按特定字段折叠之后,来丰富搜索结果的多样性。
  • 有人肯定会想到,使用term agg+ top hits agg来实现啊,这种组合两种聚和的方式可以实现上面的功能,不过也有一些局限性,比如,不能分页、结果不够精确以及数据量大的情况下聚合比较慢。
  • 而新的的字段折叠的方式是怎么实现的的呢,有这些要点:折叠+取inner_hits分两阶段执行,所以top hits永远是精确的;字段折叠只在top hits层执行,不需要每次都在完整的结果集上对为每个折叠主键计算实际的doc values值,和term agg 相比要节省很多内存;因为只在top hits上进行折叠,所以相比组合聚合的方式,速度要快很多;折叠top docs不需要使用全局序列来转换string,相比agg这也节省了很多内存;分页成为可能,和常规搜索一样,具有相同的局限,先获取from+size的内容,再合并;search_after和scroll暂未实现,不过具备可行性;折叠只影响搜索结果,不影响聚合,搜索结果的total是所有的命中纪录数,去重的结果数未知(无法计算)。
  • 来个例子:
PUT recipes
POST recipes/type/_mapping
{
  "properties": {
    "name":{
      "type": "text"
    },
    "rating":{
      "type": "float"
    },"type":{
      "type": "keyword"
    }
  }
}


POST recipes/type/
{
  "name":"清蒸鱼头","rating":1,"type":"湘菜"
}
POST recipes/type/
{
  "name":"剁椒鱼头","rating":2,"type":"湘菜"
}
POST recipes/type/
{
  "name":"红烧鲫鱼","rating":3,"type":"湘菜"
}
POST recipes/type/
{
  "name":"鲫鱼汤(辣)","rating":3,"type":"湘菜"
}
POST recipes/type/
{
  "name":"鲫鱼汤(微辣)","rating":4,"type":"湘菜"
}
POST recipes/type/
{
  "name":"鲫鱼汤(变态辣)","rating":5,"type":"湘菜"
}
POST recipes/type/
{
  "name":"广式鲫鱼汤","rating":5,"type":"粤菜"
}
POST recipes/type/
{
  "name":"鱼香肉丝","rating":2,"type":"川菜"
}
POST recipes/type/
{
  "name":"奶油鲍鱼汤","rating":2,"type":"西菜"
} 

GET recipes/type/_search
{
  "query": {
    "match": {
      "name": "鱼"
    }
  },
  "collapse": {
    "field": "type",
    "inner_hits": {
      "name": "top_rated",
      "size": 2,
      "sort": [
        {
          "rating": "desc"
        }
      ]
    }
  },
  "sort": [
    {
      "rating": {
        "order": "desc"
      }
    }
  ],
  "size": 2,
  "from": 0
}

如何做出搜索和推荐深度融合的兴趣引擎架构 田明军

搜索/推荐工作流程

阅读随手记 201704_第1张图片
搜索/推荐工作流程

一点资讯搜索/推荐架构

阅读随手记 201704_第2张图片
一点资讯搜索/推荐架构

携程实时用户行为系统实践 陈清渠

携程实时用户行为系统架构

阅读随手记 201704_第3张图片
携程实时用户行为系统架构
  • 数据有两种流向,分别是处理流和输出流。
  • 在处理流,行为日志会从客户端(App/Online/H5)上传到服务端的Collector Service。Collector Service将消息发送到分布式队列。数据处理模块由流计算框架完成,从分布式队列读出数据,处理之后把数据写入数据层,由分布式缓存和数据库集群组成。
  • 输出流相对简单,web service的后台会从数据层拉取数据,并输出给调用方,有的是内部服务调用,比如推荐系统,也有的是输出到前台,比如浏览历史。
  • 系统实现采用的是Java+Kafka+Storm+Redis+Mysql+Tomcat+Spring的技术栈。
  • 实时性:首先是用storm解决突发流量洪峰的问题,通过storm处理框架,消息能在进入kafka之后毫秒级别被处理;此外storm具有强大的scale out能力,只要通过后台修改worker数量参数,并重启topology,可以马上扩展计算能力,方便应对突发的流量洪峰;实时用户行为系统采用的at least once的策略,这种策略下消息可能会重发,所以程序处理实现了幂等支持;
  • 实时行为双队列设计:在部分情况下数据处理需要重试,但是无法连接一般需要更长时间等待网络或数据库的恢复,这种情况下处理程序不能一直等待,否则会造成数据延迟。实时用户行为系统采用了双队列的设计来解决这个问题。
阅读随手记 201704_第4张图片
实时行为双队列设计
  • 可用性:首先是系统层面上做了全栈集群化,另外系统在部分模块不可用时通过降级处理保障整个系统的可用性。

Spark技术在京东智能供应链预测的应用 杨冬越 郭景瞻

  • 背景:京东的仓库按功能划分为RDC(区域分发中心,中心城市)、FDC(区域运转中心,中小城市及边远地区)、大件中心仓、大件卫星仓、图书仓和城市仓等。京东首先从供货商采购商品到RDC,再根据实际需求调配到FDC,再运往离客户最近的配送站,由快递员送到客户手中。借助机器学习、大数据等技术,技术在很多供应链优化问题上都已经实现系统化,实现全流程自动化,在这其中预测技术起着至关重要的底层支撑作用。
  • 预测系统:主要支持三大业务:销量预测、单量预测和GMV预测。其中销量预测主要支持商品补货、商品调拨;单量预测主要支持仓库、站点的运营管理;GMV预测主要支持销售部门计划的定制。
阅读随手记 201704_第5张图片
预测系统
  • 预测系统架构:先从外部数据源获取我们所需的业务数据,然后对基础数据进行加工清洗,再通过时间序列、机器学习等人工智能技术对数据进行处理分析,最后计算出预测结果并通过多种途径推送给下游系统使用。
阅读随手记 201704_第6张图片
预测系统架构
  • 预测系统核心:基础层(HDFS用来做数据存储,Yarn用来做资源调度,BDP用来做任务调度)、框架层(以Spark RDD、Spark SQL、Hive为主)、工具层(比较常用的包有xgboost、numpy、pandas、sklearn、scipy和hyperopt等)、算法层(时间序列、机器学习和结合业务开发的一些独有的算法);
阅读随手记 201704_第7张图片
预测系统核心
  • 以机器学习算法为主的流程如下:
阅读随手记 201704_第8张图片
以机器学习算法为主的流程
  1. 特征构建:通过数据分析、模型试验确定主要特征,通过一系列任务生成标准格式的特征数据。
  2. 模型选择:不同的商品有不同的特性,所以首先会根据商品的销量高低、新品旧品、假节日敏感性等因素分配不同的算法模型。
  3. 特征选择:对一批特征进行筛选过滤不需要的特征,不同类型的商品特征不同。
  4. 样本分区:对训练数据进行分组,分成多组样本,真正训练时针对每组样本生成一个模型文件。一般是同类型商品被分成一组,比如按品类维度分组,这样做是考虑并行化以及模型的准确性。
  5. 模型参数:选择最优的模型参数,合适的参数将提高模型的准确度,因为需要对不同的参数组合分别进行模型训练和预测,所以这一步是非常耗费资源。
  6. 模型训练:待特征、模型、样本都确定好后就可以进行模型训练,训练往往会耗费很长时间,训练后会生成模型文件,存储在HDFS中。
  7. 模型预测:读取模型文件进行预测执行。
  8. 多模型择优:为了提高预测准确度,我们可能会使用多个算法模型,当每个模型的预测结果输出后系统会通过一些规则来选择一个最优的预测结果。
  9. 预测值异常拦截:我们发现越是复杂且不易解释的算法越容易出现极个别预测值异常偏高的情况,这种预测偏高无法结合历史数据进行解释,因此我们会通过一些规则将这些异常值拦截下来,并且用一个更加保守的数值代替。
  10. 模型评价:计算预测准确度,我们通常用使用mapd来作为评价指标。
  11. 误差分析:通过分析预测准确度得出一个误差在不同维度上的分布,以便给算法优化提供参考依据。

对CQRS的基础理解 张逸

  • CQRS即Command Query Responsibility Seperation(命令查询职责分离),其设计思想来源于Mayer提出的CQS(Command Query Seperation)。这种命令与查询的分离方式,可以更好地控制请求者的操作。查询操作不会造成数据的修改,因而它属于一种幂等操作,可以反复地发起,而不用担心会对系统造成影响。基于这种特性,我们还可以为其提供缓存,从而改进查询的性能。命令操作则与之相反,它会直接影响系统信息的改变。
  • 查询操作与命令操作对事务的要求也不一样。由于查询操作不会改变系统状态,因而,不会产生最终的数据不一致。从请求响应的角度来看,查询操作常常需要同步请求,实时返回结果;命令操作则不然,因为我们并不期待命令操作必须返回结果,这就可以采用fire-and-forget方式,而这种方式正是运用异步操作的前提。此外,对于大多数软件系统而言,查询操作发起的频率通常要远远高于命令操作。如上种种,都是将命令与查询进行分离的根本原因。
  • 下图是CQRS框架AxonFramework官方文档给出的CQRS架构图。在这个架构图中,最核心的概念是Command、Event。以我的理解,CQRS模式的风格源头就是基于事件的异步状态机模型。抛开命令查询分离这一核心原则,这才是CQRS的基础内容。
阅读随手记 201704_第9张图片
CQRS架构图
  • CQRS对设计者的影响,是将领域逻辑,尤其是业务流程,皆看做是一种领域对象状态迁移的过程。这一点与REST将HTTP应用协议看做是应用状态迁移的引擎,有着异曲同工之妙。这种观点(或设计视图)引出了Command与Event的概念。Command是系统中会引起状态变化的活动,通常是一种命令语气,例如注册会议RegisterToConference。至于Event,则描述了某种事件的发生,通常是命令的结果(但并不一定是直接结果,但源头一定是因为发送了命令),例如OrderConfirmed。

我对CQRS/EventSourcing架构的思考 汤雪华

  • 聚合,它通过定义对象之间清晰的所属关系和边界来实现领域模型的内聚,并避免了错综复杂的难以维护的对象关系网的形成。聚合定义了一组具有内聚关系的相关对象的集合,我们把聚合看作是一个修改数据的最小原子单元。
阅读随手记 201704_第10张图片
聚示意图
  • 聚合根:每个聚合都有一个根对象,根对象管理聚合内的其他子对象(实体、值对象),聚合之间的交互都是通过聚合根来交互,不能绕过聚合根去直接和聚合下的子实体进行交互。
  • Eventual Consistency:聚合内的数据修改,是ACID强一致性的;跨聚合的数据修改,是最终一致性的。遵守这个原则,可以让我们最大化的降低并发冲突,从而最大化的提高整个系统的吞吐。
  • In Memory:指整个系统中的所有的聚合根对象都活在内存。在In-Memory的架构下,当要修改某个聚合根的状态时,它已经在内存,我们可以直接拿到该对象的引用,且框架会尽量保证聚合根对象的状态就是最新的。聚合根是在内存中的最小计算单元,每个聚合内部都封装了业务规则,并保证数据的强一致性。
  • Event Sourcing:不保存对象的最新状态,而是保存对象产生的所有事件;通过事件溯源得到对象最新状态。
  • Event Sourcing VS CRUD:对于CRUD,DB的记录可变,可以增删改;对于ES,没有更新、删除,只有Append Event,不可变。
  • Actor Model:其核心思想是对象直接不会直接调用来通信,而是通过发消息来通信。每个Actor都有一个Mailbox,它收到的所有的消息都会先放入Mailbox中,然后Actor内部单线程处理Mailbox中的消息。从而保证对同一个Actor的任何消息的处理,都是线性的,无并发冲突。从全局上来看,就是整个系统中,有很多的Actor,每个Actor都在处理自己Mailbox中的消息,Actor之间通过发消息来通信。Akka框架就是实现Actor模型的并行开发框架,并且Akka框架融入了聚合、In-Memory、Event Sourcing这些概念。Actor非常适合作为DDD聚合根。Actor的状态修改是由事件驱动的,事件被持久化起来,然后通过Event Sourcing的技术,还原特定Actor的最新状态到内存。
阅读随手记 201704_第11张图片
Actor Model
  • 下图是CQRS架构的典型架构图。CQRS架构的核心出发点是将整个系统的架构分割为读和写两部分,从而方便我们对读写两端进行分开优化;CQRS架构的一致性模型为最终一致性。采用CQRS架构的一个前提是,你的系统要接受系统使用者查询到的数据可能不是最新的,而是有几个毫秒的延迟。
阅读随手记 201704_第12张图片
CQRS架构
  • CQRS架构的适用场景:当我们的应用的写模型和读模型差别比较大时;当我们希望实践DDD时,因为CQRS架构可以让我们实现领域模型不受任何ORM框架带来的对象和数据库的阻抗失衡的影响;当我们希望对系统的查询性能和写入性能分开进行优化时,尤其是读/写比非常高的系统,CQ分离是必须的;当我们希望我们的系统同时满足高并发的写、高并发的读的时候;因为CQRS架构可以做到C端最大化的写,Q端非常方便的提供可扩展的读模型。
  • C端的命令执行流程:发送命令到分布式MQ;然后命令的订阅者处理命令;订阅者内部根据不同的命令调用不同的Command Handler进行处理;Command Handler内部根据命令所指定的聚合根ID从In-Memory内存中直接获取聚合根对象的引用,然后操作聚合根对象;聚合根对象状态发生变化并产生事件;框架负责自动持久化事件到Event Storage;框架负责将事件发布到Event MQ;Event订阅者订阅事件,然后调用对应的Event Handler进行处理,如更新Data Storage;
  • Q端的查询执行流程:调用轻薄的Query Service,传如Query DTO;Query Service从读库进行查询并返回结果;
  • 挖掘出更多有用的特性:一个命令只允许修改一个聚合根;命令或事件在分布式MQ的路由根据聚合根ID来路由,也就是同一个聚合根的命令和事件都在一个队列里;引入Command Mailbox,Event Mailbox这两个概念,将聚合根需要处理的命令和产生的事件都队列化去并发,做到架构上最大的并行,将并发降低到最低;引入Group Commit技术,做到整个C端的架构层面支持批量提交聚合根产生的事件,从而极大的提高C端的整体吞吐量;通过引入Saga的概念,做到基于事件驱动的最终一致性;
  • Event Sourcing的优点:记录了数据完整变化过程,最详细的日志;可以将系统还原到任何一个时间点的状态;Domain Event非常有业务价值,BI分析事件能预测业务未来发展情况;可以有效解决线上的数据问题,线下重演一遍,就能知道哪里出问题;不再需要用到ORM,所以没有O/R阻抗失衡的问题,领域模型的设计可以更OO;将Command、Event串联起来,可以分析聚合根的整个变化过程,有助于排查分析问题;自动并发冲突检测、命令的幂等处理;
  • Event Sourcing的缺点:事件数量巨大,如何存储;如果单个聚合根事件过多,则重演会造成性能问题;领域模型重构被制约,事件的修改必须兼容以前的结构;数据库订正不在有效;架构实践门槛高,没有成熟框架支撑基本无望;需要具备DDD领域建模的能力;事件驱动状态的修改,思维转变难。

北大AI公开课第6讲 王俊:DNA是生命数字化的过程,AI改变生命科学 新智元

视频回放链接:http://www.iqiyi.com/l_19rrfgal1z.html

北大AI公开课第7讲 徐伟:AGI 2050年前实现可能性超50% 机器学习研究会

视频回放链接:http://www.iqiyi.com/l_19rrbkb3az.html

北大AI公开课第8讲 李航:自然语言处理——理想与现实、机遇与挑战 机器学习研究会

课程回放链接:http://www.iqiyi.com/w_19rtxrunb9.html

北大AI公开课第9讲 叶杰平:深度学习在交通领域应用潜力巨大 新智元

课程回放链接:http://www.iqiyi.com/l_19rrc5qodr.html

任何人都能看懂的TensorFlow介绍 Soon Hin Khor/机器之心

小白也能看懂的TensorFlow介绍 Soon Hin Khor/机器之心

机器学习演化史,方法、应用场景与发展趋势 新智元

机器学习演化史:各学派发展融合,最终让自动机器成为可能

阅读随手记 201704_第13张图片
机器学习演化史
  • 符号学派(Symbolists)是使用基于规则的符号系统做推理的人。这种方法主要的缺陷在于其脆弱性,因为在边缘情况下,一个僵化的知识库似乎总是不适用,但在现实中存在这种模糊性和不确定性是不可避免的。爱用方法:规则和决策树
  • 贝叶斯学派(Bayesians)是使用概率规则及其依赖关系进行推理的一派。这种方法与符号学方法的相似之处在于可以以某种方式得到对结果的解释,另一个优点是存在可以在结果中表示的不确定性的量度。爱用方法:朴素贝叶斯或马尔科夫
  • 连接学派(Connectionists)的研究者相信智能起源于高度互联的简单机制。这种方法的第一个具体形式是出现于1959年的感知器,最新的形式是深度学习。爱用方法:神经网络
  • 进化学派(Evolutionists)是应用进化的过程,例如交叉和突变以达到一种初期的智能行为的一派。在深度学习中,GA确实有被用来替代梯度下降法,所以它不是一种孤立的方法。爱用方法:遗传算法
  • 类推学派(The analogizers)更多地关注心理学和数学最优化,通过外推来进行相似性判断。类推学派遵循“最近邻”原理进行研究,各种电子商务网站上的产品推荐是类推方法最常见的示例。爱用方法:支持向量机
  • 21世纪的头十年,最显著的就是连接学派和符号学派的结合,由此产生了记忆神经网络以及能够根据知识进行简单推理的智能体,基础架构也向大规模云计算转换。第二个十年,连接学派、符号学派和贝叶斯学派也将融合到一起,而主要的局面将是感知任务由神经网络完成,但涉及到推理和行动还是需要人为编写规则;从2040年以后,根据普华永道的预测,主流学派将成为 Algorithmic convergence,也即各种算法融合在一起,届时机器自主学习,也即元学习(Meta-learning)实现,计算服务将无处不在。

机器学习:工作原理及适用场景

  • 机器学习能够通过“学习”大量的数据,在不需要人为编程的情况下,生成以及识别特定的对象,比如人脸。目前,机器学习也是商业应用中最常用的算法。
  • 机器学习是一类关注从数据中找到模式,并根据这些模式进行预测的研究和算法。机器学习属于人工智能,它与数据挖掘、统计学、模式识别等相关领域的关系如下图所示:
阅读随手记 201704_第14张图片
机器学习和人工智能的关系
  • 机器学习的主要流程步骤:选择数据(训练用数据、验证用数据、测试用数据)、数据建模(使用训练数据构建涉及相关特征的模型)、验证模型(用验证数据验证建立的模型)、调试模型(为了提升模型的性能,使用更多的数据、不同的特征,调整参数,这也是最耗时耗力的一步)、使用模型(部署模型训练好的模型,对新的数据进行预测)、测试模型(使用测试用数据验证模型,并评估模型的性能);
阅读随手记 201704_第15张图片
机器学习工作原理

实际应用机器学习:什么才是特定任务的正确算法?

机器学习中常用的算法有很多,具体需要用哪种,很大程度上取决于你手头的数据及其特征,你的训练目标,尤其是具体的使用场景。除非特殊情况,不必使用最复杂的算法。下面是常见的机器学习算法。

  • 决策树(Decision Trees):是一个决策支持工具,它使用树形图或决策模型以及序列可能性。包括各种偶然事件的后果、资源成本、功效。从商务决策的角度来看,大部分情况下,决策树是一个人为了评估做出正确决定的概率需要问的是/否问题的最小数值。它能让你以一个结构化和系统化的方式来处理这个问题,然后得出一个合乎逻辑的结论。
阅读随手记 201704_第16张图片
决策树
  • 支持向量机:是二元分类算法。给定一组两种类型的N维的地方点,SVM产生一个(N - 1)维超平面到这些点分成2组。假设你有两种类型的点,且它们是线性可分的。SVM将找到一条直线将这些点分成2种类型,并且这条直线会尽可能地远离所有的点。在规模上,目前使用SVM(在适当修改的情况下)解决的最大的问题包括显示广告、人类剪接位点识别、基于图像的性别检测和大规模的图像分类等等。
阅读随手记 201704_第17张图片
支持向量机
  • 逻辑回归:是一种强大的统计方法,它能建模出一个二项结果与一个(或多个)解释变量。它通过估算使用逻辑运算的概率,测量分类依赖变量和一个(或多个)独立的变量之间的关系,是累积的逻辑分布情况。
阅读随手记 201704_第18张图片
逻辑回归
  • 朴素贝叶斯分类:是一种十分简单的分类算法,方程P(A|B)是后验概率,P(B|A)是可能性,P(A)是类先验概率,而P(B)是预测先验概率。朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。
阅读随手记 201704_第19张图片
朴素贝叶斯分类
  • 隐马尔科夫模型通过分析可观察的数据来计算隐藏状态的概率,然后通过分析隐藏状态来估计未来可能观察到的模式。一个例子是,通过分析高气压(或低气压)的概率来预测天气是晴天、雨天或多云的可能性。
阅读随手记 201704_第20张图片
隐马尔科夫模型
  • 随机森林算法结合了多个树,使用随机挑选的数据子集,以此提升决策树的分析准确率。下图中的例子展示的是与乳腺癌复发相关的不同基因及其几率。随机深林算法的优势在于能够处理大规模数据集,以及大量看似不相关的数据,可以用于风险评估和客户信息分析。
阅读随手记 201704_第21张图片
随机森林
  • 递归神经网络:可以描述动态时间行为,因为和前馈神经网络接受较特定结构的输入不同,RNN将状态在自身网络中循环传递,因此可以接受更广泛的时间序列结构输入。手写识别是最早成功利用RNN的研究结果,其他应用还包括图像分类、图说生成和情感分析。
阅读随手记 201704_第22张图片
递归神经网络
  • 长短期记忆和门控循环单元(gated recurrent unit, GRU)神经网络同时具有长期记忆和短期记忆。换句话说,这些较新的 RNN 具有更好的记忆控制,允许先前的值持续保存,或必要时为许多序列步骤重置,避免在步骤到步骤的传递时造成“梯度衰减”(gradient decay)。LSTM 和 GRU 网络通过记忆体组(memory blocks)和被称为“门”(gates)的结构适当地 pass 或 reset 值来实现这种记忆控制。
阅读随手记 201704_第23张图片
长短期记忆
  • 卷积神经网络:是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理、药物发现等有出色表现。卷积神经网络由一个或多个卷积层和顶端的全连通层(对应经典的神经网络)组成,同时也包括关联权重和池化层。这一结构使得卷积神经网络能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网络在图像和语音识别方面能够给出更优的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网络,卷积神经网络需要估计的参数更少。
阅读随手记 201704_第24张图片
卷积神经网络

关于微服务的发展方向,我们和5位专家聊了聊 Mark Little/薛命灯

  • 使用“微服务架构”这个名字会更恰当些。它是一种架构风格,它把一系列协作的服务组织成一个系统来支撑业务。
  • 组织的沟通结构与服务架构有着更深层次的关系,这个联系比我们先前意识到的要更加紧密。
  • 要做的:监控,监控,监控;做好服务的独立部署;确保你的团队具有DevOps文化;对微服务架构的实施进行评审,并把它作为指南;让微服务仪表化、可调试,并提供度量指标,把测试作为一等公民;对容器部署技术进行评估,容器技术有很大优势。

kafka数据可靠性深度解读 朱忠华

  • Kafka与传统消息系统相比,有以下不同:它被设计为一个分布式系统,易于向外扩展;它同时为发布和订阅提供高吞吐量;它支持多订阅者,当失败时能自动平衡消费者;它将消息持久化到磁盘,因此可用于批量消费,例如ETL以及实时应用程序。
  • Kafka体系架构:一个典型的Kafka体系架构包括若干Producer、若干broker、若干Consumer (Group)以及一个Zookeeper集群。 一个topic可以认为一类消息,每个topic将被分成多个partition,每个partition在存储层面是append log文件。任何发布到此partition的消息都会被追加到log文件的尾部,每条消息在文件中的位置称为offset,offset为一个long型的数字,它唯一标记一条消息。每条消息都被append到partition中,是顺序写磁盘,因此效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是Kafka高吞吐率的一个很重要的保证)。
阅读随手记 201704_第25张图片
Kafka体系架构
  • Kafka文件存储机制:partition还可以细分为segment,一个partition物理上由多个segment组成;在Kafka文件存储中,同一个topic下有多个不同的partition,每个partiton为一个目录,partition是实际物理上的概念,而topic是逻辑上的概念;每个partition相当于一个巨型文件被平均分配到多个大小相等的segment数据文件中(每个segment 文件中消息数量不一定相等),这种特性也方已被消费消息的清理,提高磁盘的利用率;segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment索引文件和数据文件,".index”索引文件存储大量的元数据,“.log”数据文件存储大量的消息,索引文件中的元数据指向对应数据文件中message的物理偏移地址。以下图中“.index”索引文件中的元数据[3, 348]为例,在“.log”数据文件表示第3个消息,即在全局partition中表示170410+3=170413个消息,该消息的物理偏移地址为348。怎么知道何时读完本条消息,消息都具有固定的物理结构,可以确定一条消息的大小,即读取到哪里截止。
阅读随手记 201704_第26张图片
segment文件组成
  • 复制原理和同步方式:为了提高消息的可靠性,Kafka每个topic的partition有N个副本,其中N是topic的复制因子的个数。Kafka通过多副本机制实现故障自动转移,当Kafka集群中一个broker失效情况下仍然保证服务可用。在Kafka中发生复制时确保partition的日志能有序地写到其他节点上,N个replicas中,其中一个replica为leader,其他都为follower,leader处理partition的所有读写请求,与此同时,follower会被动定期地去复制leader上的数据。Kafka提供了数据复制算法保证,如果leader发生故障或挂掉,一个新leader被选举并被接受客户端的消息成功写入。
阅读随手记 201704_第27张图片
Kafka复制原理
  • 副本同步:HW俗称高水位,HighWatermark的缩写,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置。另外每个replica都有HW,leader和follower各自负责更新自己的HW的状态。对于leader新写入的消息,consumer不能立刻消费,leader会等待该消息被所有ISR中的replicas同步后更新HW,此时消息才能被consumer消费。这样就保证了如果leader所在的broker失效,该消息仍然可以从新选举的leader中获取。由此可见,Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。
阅读随手记 201704_第28张图片
副本同步
  • 数据可靠性和持久性保证:当producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别,1表示leader已成功收到的数据并得到确认,0表示无需等待确认,-1表示需要等待所有follower确认接收到数据。如果要提高数据的可靠性,在设置request.required.acks=-1的同时,也要min.insync.replicas这个参数(表示ISR中的最小副本数是多少,可以在broker或者topic层面进行设置)的配合,这样才能发挥最大的功效。

  • 关于HW的进一步探讨:一个partition中的ISR列表中,leader的HW是所有ISR列表里副本中最小的那个的LEO。如下图这个时候A机器宕机,如果B成为leader,假如没有HW,在A重新恢复之后会做同步操作,在宕机时log文件之后直接做追加操作,而假如B的LEO已经达到了A的LEO,会产生数据不一致的情况,所以使用HW来避免这种情况。A在做同步操作的时候,先将log文件截断到之前自己的HW的位置,即3,之后再从B中拉取消息进行同步。

阅读随手记 201704_第29张图片
关于HW的进一步探讨
  • Leader选举:一个基本的原则就是,如果leader不在了,新的leader必须拥有原来的leader commit的所有消息。Kafka在Zookeeper中为每一个partition动态的维护了一个ISR,这个ISR里的所有replica都跟上了leader,只有ISR里的成员才能有被选为leader的可能(unclean.leader.election.enable=false)。在这种模式下,对于f+1个副本,一个Kafka topic能在保证不丢失已经commit消息的前提下容忍f个副本的失败,在大多数使用场景下,这种模式是十分有利的。事实上,为了容忍f个副本的失败,“少数服从多数”的方式和ISR在commit前需要等待的副本的数量是一样的,但是ISR需要的总的副本的个数几乎是“少数服从多数”的方式的一半。但如果某一个partition的所有replica都挂了,Kafka默认采用选择第一个“活”过来的replica(并不一定是在ISR中)作为leader,可以通过参数unclean.leader.election.enable=false设置为等待ISR中任意一个replica“活”过来,并且选它作为leader;

  • Kafka的发送模式:由producer端的配置参数producer.type来设置,这个参数指定了在后台线程中消息的发送方式是同步的还是异步的,默认是同步的方式。如果设置成异步的模式,可以是producer以batch的形式push数据,这样会极大的提高broker的性能,但是这样会增加丢失数据的风险。

  • 消息去重:Kafka在producer端和consumer端都会出现消息的重复,这就需要去重处理。Kafka文档中提及GUID(Globally Unique Identifier)的概念,通过客户端生成算法得到每个消息的unique id,同时可映射至broker上存储的地址,即通过GUID便可查询提取消息内容,也便于发送方的幂等性保证,需要在broker上提供此去重处理模块,目前版本尚不支持。建议业务方根据自身的业务特点进行去重,比如业务消息本身具备幂等性,或者借助Redis等其他产品进行去重处理。

  • 要保证数据写入到Kafka是安全的,高可靠的,需要如下的配置:

topic的配置:replication.factor>=3,即副本数至少是3个;2<=min.insync.replicas<=replication.factor
broker的配置:leader的选举条件unclean.leader.election.enable=false
producer的配置:request.required.acks=-1(all),producer.type=sync
  • 测试场景总结:
当acks=-1时,Kafka发送端的TPS受限于topic的副本数量(ISR中),副本越多TPS越低;
acks=0时,TPS最高,其次为1,最差为-1,即TPS:acks_0 > acks_1 > ack_-1;
min.insync.replicas参数不影响TPS;
partition的不同会影响TPS,随着partition的个数的增长TPS会有所增长,但并不是一直成正比关系,到达一定临界值时,partition数量的增加反而会使TPS略微降低;
Kafka在acks=-1,min.insync.replicas>=1时,具有高可靠性,所有成功返回的消息都可以落盘。

聊聊分布式定时任务中间件架构及其实现 张亮

  • 分布式定时任务中间件的关注点从易到难是:集中化 -> 高可用 –> 弹性化。
  • 去中心化架构是指所有的作业节点都是对等的。每个作业从注册中心拉取自己的执行时间并且各自定时执行,执行时均使用作业服务器的本地时钟,在作业无需分片调整时并不会对注册中心产生写操作,进而不会导致注册中心更新缓存,因此执行效率很高,去中心化架构的优点是轻量级,仅提供一个lib就可以与业务代码一同工作,部署成本低,只需搭建注册中心即可,缺点是如果各作业服务器时钟不一致会产生同一作业的不同分片运行有先有后,缺乏统一调度。并且不能跨语言。
  • 中心化架构将系统分为调度节点和执行节点。由调度节点发起作业的分片和执行,然后通过RPC发布给作业执行节点,或者通过写注册中心让监听注册中心的作业执行节点主动触发。中心化架构模式可以解决服务器时间差以及跨语言的问题。缺点是部署和运维稍复杂,需要单独部署调度节点并需要维护其高可用,这也会造成一定的资源浪费。
  • Elastic-Job是一个纯Java实现的分布式方案,提供无中心化解决方案。它采用all in jar的理念,使用时无需区分主从或调度、执行节点,一切都采用自我协调。Elastic-Job采用ZooKeeper作为注册中心,用于处理作业的高可用、分片、失效转移等分布式协调功能。每个使用Elastic-Job的应用都需要与ZooKeeper建立连接,这样会造成ZooKeeper的连接过多,容易成为分布式ZooKeeper的瓶颈。Elastic-Job的架构图如下:
阅读随手记 201704_第30张图片
Elastic-Job的架构图
  • Elastic-Job-Cloud包括Mesos Framework的Scheduler和Customized Executor两部分。Elastic-Job-Cloud采用中心节点分片,直接将分片任务转化为Mesos的TaskInfo,这样就屏蔽了IP地址的限制。Elastic-Job-Cloud的作业调度采用两个队列,Offer队列用于收集Mesos分配的资源,Job队列用于堆积待执行作业。当待执行作业可以从资源队列中匹配到合适的资源时,才会分配并生成TaskInfo执行。
阅读随手记 201704_第31张图片
Elastic-Job-Cloud的架构图

2017年会是Serverless爆发之年吗? 麦克周

  • 开发人员进行业务开发时,仍然需要关心很多和服务器相关的服务端开发工作,比如缓存、消息服务、Web应用服务器、数据库,以及对服务器进行性能优化,还需要考虑存储和计算资源,考虑负载均衡和横向扩展能力,考虑服务器容灾稳定性等非专业逻辑的开发。这些服务器的运维和开发知识、经验极大地限制了开发者进行业务开发的效率。
  • 2014年,云厂商AWS推出了“无服务器”的范式服务。最初“无服务器”意在帮助开发者摆脱运行后端应用程序所需的服务器设备的设置和管理工作。这项技术的目标并不是为了实现真正意义上的“无服务器”,而是指由第三方供应商负责后端基础结构的维护,以服务的方式为开发者提供所需功能。现在,无服务器架构是指大量依赖第三方服务(也叫做后端即服务,即“BaaS”)或暂存容器中运行的自定义代码(函数即服务,即“FaaS”)的应用程序,函数是无服务器架构中抽象语言运行时的最小单位,在这种架构中,我们并不看重运行一个函数需要多少CPU或RAM或任何其他资源,而是更看重运行函数所需的时间,我们也只为这些函数的运行时间付费。无服务器架构中函数可以多种方式触发,如定期运行函数的定时器、HTTP请求或某些相关服务中的某个事件。
  • Serverless案例:以带有服务功能逻辑的传统面向客户端的三层应用为例,如果采用Serverless架构来对该应用进行改造,则架构如图所示:删除认证逻辑,用第三方BaaS服务替代;使用另外一个BaaS,允许客户端直接访问第三方上面的数据子库;以前运行在服务端的逻辑转移到客户端中,例如跟踪用户访问,客户端则慢慢转化为单页面应用;计算敏感或者需要访问大量数据的功能,例如搜索这类应用,我们不需要运行一个专用服务,而是通过FaaS模块,通过API Gateway对HTTP访问提供响应;最后,可以将其他功能用另外一个FaaS功能取代,因为安全原因放在服务端还不如在客户端重新实现,当然前端还是API Gateway。
  • Serverless架构原则: 按需使用计算服务执行代码;编写单一用途的无状态函数;设计基于推送的、事件驱动的管道;创建更强大的前端;与第三方服务集成;
阅读随手记 201704_第32张图片
Serverless案例

Java 9新特性介绍及Jigsaw一览 QCON/杨晓峰

  • Jigsaw的目标:提供两方面的基本能力(可靠的配置替换脆弱的classpath机制以及强),带来的好处(可扩展性+可维护性+安全);
阅读随手记 201704_第33张图片
Jigsaw项目
  • 模块系统组成:
阅读随手记 201704_第34张图片
模块系统组成
  • JDK自身的代码被划分为一组模块:
阅读随手记 201704_第35张图片
JDK自身模块组成
  • 典型的模块描述文件:
阅读随手记 201704_第36张图片
模块描述文件
  • 可见性:完全public、只对特定的模块public、只在模块内public、protected、package内可见、private;
  • Java模块的分类:命名模块、自动命名模块、匿名模块;
阅读随手记 201704_第37张图片
Java模块的分类
  • 升级影响:
阅读随手记 201704_第38张图片
Java模块的分类

打造高性能高可用的搜索服务——爱奇艺搜索架构实践 QCON/陈爱云

  • 视频搜索难点和痛点:索引量大、高并发、低延时、索引更新速度快;
  • 爱奇艺搜索架构:应用网络抖动(优先访问本机redis);搜索分级(热门索引和全量索引机器4:1,热门索引可以服务80%的请求,节省机器);索引更新(全量数据7天更新一次、增量数据每天更新、实时数据实时更新);从同步到异步(包括http和rpc);性能优化(基于CPU和内存的优化);
阅读随手记 201704_第39张图片
爱奇艺搜索架构
  • 高可用:异地多活、降级(client根据server的成功率和响应时间降级,server根据队列长度、平均处理时间和CPU判断是否需要降级,两种降级方法,取长时间缓存和去除一些不重要的计算)、限流、扩容(使用docker自动扩容,使用jenkins一键部署)、监控系统、Trace系统。

高速发展业务的架构应对实践 QCON/陈霖

  • 外卖产品特点:交易量大,峰值集中;交易过程复杂;履约流程较长;
  • 百度外卖架构:
阅读随手记 201704_第40张图片
百度外卖架构
  • 服务分层情况:
阅读随手记 201704_第41张图片
服务分层情况
  • 基础服务优化:流量接入层(七层负载均衡、流量镜像、业务限流);Redis异地多活(非强一致性、实时读写本region数据、通过MQ同步aof并在当前region进行merge);服务治理(统一RPC框架、超时重试、过载保护、柔性服务、分布式跟踪、全局超时控制)。

美团点评旅游推荐系统的演进 QCON/郑刚

  • 旅游推荐面临的问题:本异地差距大、推荐形式多样、季节性明显、需求个性化;
  • 用户画像
阅读随手记 201704_第42张图片
用户画像
  • 基于用户画像的推荐
阅读随手记 201704_第43张图片
基于用户画像的推荐
  • 问题建模
阅读随手记 201704_第44张图片
问题建模
  • 特征工程
阅读随手记 201704_第45张图片
特征工程
  • 模型训练
阅读随手记 201704_第46张图片
模型训练
  • 从海量大数据的离线计算到高并发在线服务的推荐引擎架构设计
阅读随手记 201704_第47张图片
推荐引擎架构设计
  • 总结
阅读随手记 201704_第48张图片
总结

深度学习在电子商务中的应用 QCON/程进兴

  • 目前商品搜索中的语义词汇差异问题:如理发器、理发推子、电推子;血糖计和血糖仪;
  • 矢量化搜索模型:传统搜索基于文字匹配,商品包含搜索词或者不包含搜索词;利用深度学习技术,将搜索词和商品全部数值矢量化,将文字匹配转化为数值矢量计算;词语矢量化是进一步进行各种深度学习的基础;
  • 基于词语聚类的矢量化模型:Word2vec等工具可以有效地将词语转化为向量;将句子/段落/文章有效转化为向量则有很大的挑战;电商搜索中遇到的主要是句子/短文分析,可以将短文中的词语聚类,挑选具有代表性的词语聚类结果,来表示整个短文;传统聚类(如Kmeans)在几何距离的基础上进行聚类,效果不好,利用随机过程做词语聚类可以解决这一问题;
  • 基于用户反馈的矢量化:把搜索词和商品文档各自作为整体看待,直接学习训练各自的矢量值;通过分析用户每次访问的行为顺序,构建有“搜索词”和“商品文档”组成的句子;训练集是采用苏宁易购的用户搜索日志作为来源,在经过数据清理之后,按照搜索的时间顺序,结合商品的点击,商品放入购物车,商品的购买这些用户行为,而建立的矢量化训练数据;
阅读随手记 201704_第49张图片
基于用户反馈的矢量化模型

微信红包后台系统可用性设计实践 QCON/michaelfang

  • 微信红包的系统流程:发、包、抢、拆;
阅读随手记 201704_第50张图片
微信红包的系统流程
  • 微信红包的系统架构
阅读随手记 201704_第51张图片
微信红包的系统架构
  • 可用性影响因素:计划外(系统级故障、数据和中介故障、其他);计划外(日常任务、运维相关、升级相关);
  • 可用性设计方向:降低意外故障影响(业务逻辑层:部署方案、异步化、降级与柔性;订单存储层:SET化、DB故障自愈能力建设)、平行扩缩容;
阅读随手记 201704_第52张图片
改进后的平行扩容

异构系统链路追踪——滴滴 trace 实践 QCON

阅读随手记 201704_第53张图片
背景
阅读随手记 201704_第54张图片
诉求
阅读随手记 201704_第55张图片
方案
阅读随手记 201704_第56张图片
Trace机制
阅读随手记 201704_第57张图片
Trace落地
阅读随手记 201704_第58张图片
规划

Leaf——美团点评分布式ID生成系统 照东

  • 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。业务系统对ID号的要求有全局唯一性、趋势递增、单调递增、信息安全、可用性要求极高;ID生成系统应该做到如下几点:平均延迟和TP999延迟都要尽可能低;可用性5个9;高QPS。
  • 常见方法介绍:UUID(性能非常高但不易于存储);类snowflake方案(整个ID都是趋势递增的而且灵活,缺点是强依赖机器时钟);数据库生成(单调递增且简单,缺点是强依赖DB且会有性能瓶颈);
  • Leaf-segment数据库方案:利用proxy server批量获取,每次获取一个segment(step决定大小)号段的值,用完之后再去数据库获取新的号段,可以大大的减轻数据库的压力;各个业务不同的发号需求用biz_tag字段来区分,每个biz-tag的ID获取相互隔离,互不影响,如果以后有性能需求需要对数据库扩容,不需要上述描述的复杂的扩容操作,只需要对biz_tag分库分表就行。数据库表设计如下:
阅读随手记 201704_第59张图片
biz_tag表设计
阅读随手记 201704_第60张图片
使用场景
  • Leaf-segment数据库方案的优点:Leaf服务可以很方便的线性扩展,性能完全能够支撑大多数业务场景;ID号码是趋势递增的8byte的64位数字,满足上述数据库存储的主键要求;容灾性高,Leaf服务内部有号段缓存,即使DB宕机,短时间内Leaf仍能正常对外提供服务;可以自定义max_id的大小,非常方便业务从原有的ID方式上迁移过来。
  • Leaf-segment数据库方案的缺点:ID号码不够随机,能够泄露发号数量的信息,不太安全;TP999数据波动大,当号段使用完之后还是会hang在更新数据库的I/O上,tg999数据会出现偶尔的尖刺(优化:采用双buffer的方式,Leaf服务内部有两个号段缓存区segment,当前号段已下发10%时,如果下一个号段未更新,则另启一个更新线程去更新下一个号段,当前号段全部下发完后,如果下个号段准备好了则切换到下个号段为当前segment接着下发,循环往复);DB宕机会造成整个系统不可用(优化:采用一主两从的方式,同时分机房部署,Master和Slave之间采用半同步方式同步数据);
  • Leaf-snowflake方案:完全沿用snowflake方案的bit位设计,即是“1+41+10+12”的方式组装ID号。使用Zookeeper持久顺序节点的特性自动对snowflake节点配置wokerID。Leaf-snowflake是按照下面几个步骤启动的:启动Leaf-snowflake服务,连接Zookeeper,在leaf_forever父节点下检查自己是否已经注册过(是否有该顺序子节点);如果有注册过直接取回自己的workerID(zk顺序节点生成的int类型ID号),启动服务;如果没有注册过,就在该父节点下面创建一个持久顺序节点,创建成功后取回顺序号当做自己的workerID号,启动服务。
阅读随手记 201704_第61张图片
Leaf-snowflake设计
  • Leaf-snowflake方案要点:弱依赖ZooKeeper(除了每次会去ZK拿数据以外,也会在本机文件系统上缓存一个workerID文件,当ZooKeeper出现问题,恰好机器出现问题需要重启时,能保证服务能够正常启动);解决时钟问题(如果机器的时钟发生了回拨,那么就会有可能生成重复的ID号,需要解决时钟回退的问题,见下图)。
阅读随手记 201704_第62张图片
解决时钟问题

DevOps详解 Jerome Kehrli/大愚若智

  • DevOps并不是某一套工具,DevOps是一种方法论,其中包含一系列基本原则和实践,而所用的工具只是为了对这样的实践提供支持。
  • DevOps是一种方法论,是一系列可以帮助开发者和运维人员在实现各自目标的前提下,向自己的客户或用户交付最大化价值及最高质量成果的基本原则和实践。
  • DevOps鼓励软件开发者和IT运维人员之间所进行的沟通、协作、集成和自动化,借此有助于改善双方在交付软件过程中的速度和质量。
  • DevOps团队更侧重于通过标准化开发环境和自动化交付流程改善交付工作的可预测性、效率、安全性,以及可维护性。理想情况下,DevOps可以为开发者提供更可控的生产环境,帮助他们更好地理解生产基础架构。
  • 那么核心原则到底是什么?基础架构即代码、持续交付、协作;

到底什么时候该使用MQ? 58沈剑

  • MQ是一个互联网架构中常见的解耦利器。
  • 什么时候不使用MQ?上游实时关注执行结果;
  • 什么时候使用MQ?数据驱动的任务依赖、上游不关心多下游执行结果、异步返回执行时间长;

换IP的是你,凭啥重启的却是我? 58沈剑

  • 缘起:数据库换了一个ip,此时往往连接此数据库的上游需要修改配置重启,这是一个“架构耦合”的问题,是一个架构设计上“反向依赖”的问题;
  • 常见的“反向依赖”与优化方案:公共库导致耦合(业务垂直拆分、服务化);服务化不彻底导致耦合(业务特性代码上浮,业务共性代码下沉,彻底解耦);notify的不合理实现导致的耦合(通过MQ实现解耦);配置中的ip导致上下游耦合(通过内网域名而不是ip来进行下游连接);下游扩容导致上下游耦合;

“配置”也有架构演进?看完深有痛感 58沈剑

  • 缘起:服务化分层后依赖关系会变得非常复杂,为了保证高可用,一个底层服务往往是若干个节点形成一个集群提供服务,当服务集群增减节点的时候,是否存在“反向依赖”,是否“耦合”,是否上游调用方需要修改配置重启,是否能做到上游无感知,即“配置的架构变迁”。
  • “配置私藏”是配置文件架构的最初级阶段,上游调用下游,每个上游都有一个专属的私有配置文件,记录被调用下游的每个节点配置信息。调用方很痛,容量变化的是你,凭啥修改配置重启的是我?这是一个典型的“反向依赖”架构设计,上下游通过配置耦合,值得优化;服务方很痛,ta不知道有多少个上游调用了自己;
  • “全局配置”法:对于通用的服务,建立全局配置文件,消除配置私藏:运维层面制定规范,新建全局配置文件,例如/opt/globalconf/global.conf,如果配置较多,注意做好配置的垂直拆分;对于服务方,如果是通用的服务,集群信息配置在global.conf里;对于调用方,调用方禁止配置私藏,必须从global.conf里读取通用下游配置。不足是如果调用方一直不重启,就没有办法将流量迁移到新集群上去了。可以通过文件监控组件和动态连接池组件实现自动流量迁移。
  • 全局配置文件是一个能够快速落地的,解决“修改配置重启”问题的方案,但它仍然解决不了,服务提供方“不知道有多少个上游调用了自己”这个问题,这个可以采用“配置中心”来解决。对比“全局配置”与“配置中心”的架构图,会发现配置由静态的文件 升级为动态的服务:整个配置中心子系统由zk、conf-center服务,DB配置存储与,conf-web配置后台组成;所有下游服务的配置,通过后台设置在配置中心里;所有上游需要拉取配置,需要去配置中心注册,拉取下游服务配置信息。不足是系统复杂度相对较高,对配置中心的可靠性要求较高,一处挂全局挂。

免责声明:相关链接版本为原作者所有,如有侵权,请告知删除。

随手记系列:

  • 阅读随手记 201703
  • 阅读随手记 201702
  • 阅读随手记 201701
  • 阅读随手记 201612
阅读随手记 201704_第63张图片
扫一扫 关注我的微信公众号

你可能感兴趣的:(阅读随手记 201704)