《高可用架构第1卷【1】》——高可用架构案例精选

  • 内容老,15年16年的,篇数多因此就很细碎,都是博客文之类的,没用node

  • 微信公众号的合集 略贵。 不少内容讲述 比较浅显 没有涉及到技术细节 。mysql

  • 能够参考,但不少知识、技术是2015年左右的,不适合如今;每篇文章末尾的QA颇有意思,不少问题问到点子上了nginx

     

     

    第1 章 高可用架构案例精选 1
    郭斯杰/1.1 Twitter 高性能分布式日志系统架构解析 1
    1.1.1 为何须要分布式日志. 1
    1.1.2 Twitter 如何考虑这个问题 4
    1.1.3 基于Apache BookKeeper 构建DistributeLog 5
    1.1.4 DistributeLog 案例分享13
    1.1.5 疑问与解惑.13golang

    如何使用日志在Manhattan(Twitter 的最终一致性分布式 KV数据库)中实现 compare-and-set CAS这样的强一致性操做redis

     

    用日志来序列化全部请求;算法

    到此为止,你能够看出日志的好处。它将一个本来复杂的问题变得简单。

    这种解决问题的思路叫作 Pub/Sub。而日志就是 Pub/Sub 模式的基础。

    由于 Pub/Sub 这个模式是那么简单并且强有力,这让咱们思考,是否是能够构建一个高可用的分布式日志服务,全部在 Twitter 的分布式系统均可以复用这个日志服务?

    构建一个分布式日志系统,首要的事情就是找出咱们须要解决什么问题,知足什么样的需求。sql

     

    首先做为一个基本设施,存储在日志中的数据须要持久化,这样它能够容忍宕机,避免数据丢失。数据库

     

    由于须要做为分布式系统的基础设施,那么在单机上持久化是远远不够的。咱们须要将数据复制到多台机器上,提升数据和系统的可用性。后端

     

    当数据被复制到多台机器上的时候,咱们就须要保证数据的强一致性。不然,若是咱们出现丢数据、数据不一致,那么势必影响到构建在分布式日志上的全部系统。若是日志都不能相信了,你的生活还能相信谁呢 :)api

     

     

     

     持久化 多副本 一致性

     

    在设计这个分布式日志系统 DistributedLog 的时候,咱们进行了各类调研。也同时基于运维已有系统 (kestrel, Kafka) 的经验,咱们最终决定基于 Apache BookKeeper进行构建。

    主要由于 Apache BookKeeper 提供的三个核心特性:I/O 分离、并行复制和容易理解的一致性模型。它们可以很好地知足咱们对于持久化、多副本和一致性的要求。

     

    Apache BookKeeper 没有将很复杂的一致性机制捆绑在一块儿。写者和读者之间也没有很复杂的协同机制。全部的一致性的协调就是经过这个 LAC 指针 (Last Add Confirmed)。这样的作法,能够使得扩展写者和扩展读者相互分离。

     

     

     

    Q & A
    一、日志顺序方面,日志的序列号(1,2,3,4……),是否使用了 Twitter 的 snowflake 服务?获取序列号后再推送日志?是上面提到的什么组件作的?

    没有使用 Twitter 的 snowflake 服务。由于 Writer 是 single writer,存在 ownership。全部的写会 forward 给 owner 进行序列化

     

    二、这是 Kafka 的替代产品吗?

    是的。Kafka 目前没有被使用在数据库日志的场景。由于 Kafka 的每一个 topic 对应一个文件,在 topic 数量特别多,且须要持久化的场景,Kafka 的性能比较差。很难适用于 Twitter 的多租户场景。

     

    三、请问是否研究过 ELK,请问在前面分享的架构中,哪一个对应 ELK 中的 Logstash(或fluentd)部分?或是 BookKeeper 就是替换它的?

    这里的日志就是数据库的日志。跟平常的文本日志不同。在 ELK 架构中,E 是文本的索引,K 是 UI。这两个部分不是 DistributedLog/BookKeeper 所解决的问题。DistributedLog/BookKeeper 能够做为 PUB/SUB 这样的消息中间件来作日志的中转,也就是能够用在 L 的部分。

     

    四、分享中提到的 Kestrel 和 Kafka 一个在线 ,一个离线,具体差别是什么?

    Kestrel 主要是 producer/consumer queue 的模型。而 Kafka 是 pub/sub 模型Kestrel 支持 per item 的 transaction,粒度是 item。而 Kafka 的粒度是 partition

     

    五、Name Log 的具体机制是什么样的? Client 删除日志时怎样保证与读者和写者不冲突?

    Name Log 是 DistributedLog 提供的用户接口。底层分块成不一样的 Ledgers 进行存储。元数据记录在 ZooKeeper。使用 ZooKeeper 的 CAS 操做和 notification 机制来协调。

     

    六、想多了解一下跨数据中心复制,感受很差作。能否介绍一下?

    这个问题比较宽泛。跨数据中心,能够是异步复制,也能够是同步复制。不一样场景有不一样的权衡。

     

    七、若是 LAC 以后的那条记录始终不能写成功,是否是就阻塞在那里,LAC 就无法移动了?

    这是一个很好的问题。Ensemble Change 可以保证写永远 go through。因此 LAC 会被 update 到 bookies。读方面的 Speculative 机制保证能读到 LAC。

    八、 这里的 writer 是 Write Proxy 吗?若是是的话,single writer 的吞吐量就是这个 ledger 的最大写的吞吐量了吧,会不会成为瓶颈?

    这里的 Writer 是指 Write Proxy。首先,一个 Ledger 的吞吐量,取决于 Bookie 的磁盘/网络带宽。假设,Bookie 的网卡是 1Gbps,一块磁盘做为日志写的磁盘,那么在保证低延时的状况下,Bookie 的吞吐能够达到 50MB/s~70MB/s。在 BookKeeper,能够经过配置 Ledger 的 Ensemble Size, Write Quorum Size 和 Ack Quorum Size,经过 Stripping 写的方式来提升 Ledger 的吞吐。好比,设置 Ensemble Size 为 6, Write Quorum Size 为 3, Ack Quorum Size 为 2。那么吞吐量能够提升到 2 倍。这是 Ledger 内的 Scalability。

    九、 Failover 到其余 Proxy Server 时,如何继续产生递增的 Entry ID?
    在 failover 到其余 Proxy Server 时,DistributedLog 并不会复用上一个 Proxy Server 的 ledger。因此 failover 以后,它会关闭上个 Proxy Server 写的 ledger,而后从新开一个 ledger 进行写入。递增的 Entry ID 是基于当前 ledger 生成的。从整个日志的角度来看,<ledger id, entry id> 构成了 unique 的记录 ID。若是对于 consensus 算法有所了解,可能会知道 `epoch` 的概念。每一个 epoch 会有一个 designated 的 leader。而在 DistributedLog 中,`ledger id` 其实扮演着 `epoch` 的概念。
    ————————————————
    版权声明:本文为CSDN博主「高可用架构」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接及本声明。
    原文连接:https://blog.csdn.net/weixin_45583158/article/details/100142918

     


    颜国平/1.2 腾讯基于用户画像大数据的电商防刷架构.16
    1.2.1 背景介绍16
    1.2.2 黑产现状介绍16
    1.2.3 腾讯内部防刷架构18
    1.2.4 腾讯大数据收集维度.20
    1.2.5 腾讯大数据处理平台——魔方21
    1.2.6 疑问与解惑.24

     

     

     

     

     
     

    二、矩阵式逻辑框架

     

    咱们以黑分类器为例来剖析下分类器的整个逻辑框架。

     

    总的来说咱们采用了矩阵式的逻辑框架,最开始的黑分类器咱们也是一把抓,随意的创建一个个针对黑产的检测规则、模型。

     

    结果发现不是这个逻辑漏过了,而是那个逻辑误伤量大,要对那一类的帐号增强安全打击力度,改动起来也很是麻烦。

     

    所以咱们就设计了这个一个矩阵式的框架来解决上述问题。

     

    矩阵的横向采用了Adaboost方法,该方法是一种迭代算法,其核心思想是针对同一个训练集训练不一样的弱分类器,而后把这些分类器集合起来,构成一个最终的分类器。

     

    而咱们这里每个弱分类器都只能解决一种账号类型的安全风险判断,集中起来才能解决全部帐户的风险检测。

     

    那么在工程实践上带来三个好处:

     

    1. 便于实现轻重分离,好比某平台虚假帐号集中在邮箱帐号,策略就能够加大对邮箱帐号的打击力度,影响范围也局限在邮箱账号,而不是该平台全部的帐号。

    2. 减小模型训练的难度,模型训练最大的难度在于样本的均衡性问题,拆分红子问题,就不须要考虑不一样帐号类型之间的数据配比、均衡性问题,大大下降了模型训练时正负样本比率的问题。

    3. 逻辑的健壮性,某一个分类器的训练出现了问题,受影响的范围不至于扩展到全局。

     

    矩阵纵向采用了Bagging方法,该方法是一种用来提升学习算法准确度的方法,该方法在同一个训练集合上构造预测函数系列,而后以必定的方法将他们组合成一个预测函数,从而来提升预测结果的准确性。

     


    王渊命/1.3 如何设计相似微信的多终端数据同步协议:Grouk 实践分享.26
    1.3.1 移动互联网时代多终端数据同步面临的挑战26
    1.3.2 多终端数据同步与传统消息投递协议的差别27
    1.3.3 Grouk 在多终端数据同步协议上的探索实践.28
    1.3.4 疑问与解惑.32
    周 洋/1.4 如何实现支持数亿用户的长连消息系统:Golang 高并发案例33
    1.4.1 关于push 系统对比与性能指标的讨论.33
    1.4.2 消息系统架构介绍35
    1.4.3 哪些因素决定推送系统的效果37
    1.4.4 GO 语言开发问题与解决方案.38
    1.4.5 消息系统的运维及测试41
    1.4.6 疑问与解惑.42

    360消息系统介绍

     

    360消息系统更确切的说是长链接push系统,目前服务于360内部多个产品,开发平台数千款app,也支持部分聊天业务场景,单通道多app复用,支持上行数据,提供接入方不一样粒度的上行数据和用户状态回调服务。

     

    目前整个系统按不一样业务分红9个功能完整的集群,部署在多个idc上(每一个集群覆盖不一样的idc),实时在线数亿量级。一般状况下,pc,手机,甚至是智能硬件上的360产品的push消息,基本上是从咱们系统发出的。

     

    关于push系统对比与性能指标的讨论

     

    不少同行比较关心go语言在实现push系统上的性能问题,单机性能究竟如何,可否和其余语言实现的相似系统作对比么?甚至问若是是创业,第三方云推送平台,推荐哪一个?

     

    其实各大厂都有相似的push系统,市场上也有相似功能的云服务。包括咱们公司早期也有erlang,nodejs实现的相似系统,也一度被公司要求作相似的对比测试。我感受在讨论对比数据的时候,很难保证你们环境和需求的统一,我只能说下我这里的体会,数据是有的,但这个数据前面估计会有不少定语~

     

    第一个重要指标:单机的链接数指标

     

    作过长链接的同行,应该有体会,若是在稳定链接状况下,链接数这个指标,在没有网络吞吐状况下对比,其实意义每每不大,维持链接消耗cpu资源很小,每条链接tcp协议栈会占约4k的内存开销,系统参数调整后,咱们单机测试数据,最高也是能够达到单实例300w长链接。但作更高的测试,我我的感受意义不大。

     

    由于实际网络环境下,单实例300w长链接,从理论上算压力就很大:实际弱网络环境下,移动客户端的断线率很高,假设每秒有1000分之一的用户断线重连。300w长链接,每秒新建链接达到3w,这同时连入的3w用户,要进行注册,加载离线存储等对内rpc调用,另外300w长链接的用户心跳须要维持,假设心跳300s一次,心跳包每秒须要1w tps。单播和多播数据的转发,广播数据的转发,自己也要响应内部的rpc调用,300w长链接状况下,gc带来的压力,内部接口的响应延迟可否稳定保障。这些集中在一个实例中,可用性是一个挑战。因此线上单实例不会hold很高的长链接,实际状况也要根据接入客户端网络情况来决定

     

    第二个重要指标:消息系统的内存使用量指标

     

    这一点上,使用go语言状况下,因为协程的缘由,会有一部分额外开销。可是要作两个推送系统的对比,也有些须要肯定问题。好比系统从设计上是否须要全双工(即读写是否须要同时进行)若是半双工,理论上对一个用户的链接只须要使用一个协程便可(这种状况下,对用户的断线检测可能会有延时),若是是全双工,那读/写各一个协程。两种场景内存开销是有区别的。

     

    另外测试数据的大小每每决定咱们对链接上设置的读写buffer是多大,是全局复用的,仍是每一个链接上独享的,仍是动态申请的。另外是否全双工也决定buffer怎么开。不一样的策略,可能在不一样状况的测试中表现不同。

     

    第三个重要指标:每秒消息下发量

     

    这一点上,也要看咱们对消息到达的QoS级别(回复ack策略区别),另外看架构策略,每种策略有其更适用的场景,是纯粹推?仍是推拉结合?甚至是否开启了消息日志?日志库的实现机制、以及缓冲开多大?flush策略……这些都影响整个系统的吞吐量。

     

    另外为了HA,增长了内部通讯成本,为了不一些小几率事件,提供闪断补偿策略,这些都要考虑进去。若是全部的都去掉,那就是比较基础库的性能了。

     

    因此我只能给出大概数据,24核,64G的服务器上,在QoS为message at least,纯粹推,消息体256B~1kB状况下,单个实例100w实际用户(200w+)协程,峰值能够达到2~5w的QPS...内存能够稳定在25G左右,gc时间在200~800ms左右(还有优化空间)。

     

    咱们正常线上单实例用户控制在80w之内,单机最多两个实例。事实上,整个系统在推送的需求上,对高峰的输出不是提速,每每是进行限速,以防push系统瞬时的高吞吐量,转化成对接入方业务服务器的ddos攻击因此对于性能上,我感受你们能够放心使用,至少在咱们这个量级上,经受过考验,go1.5到来后,确实有以前投资又增值了的感受。

     

    关于推送的服务端架构

     

    常见的推送模型有长轮训拉取,服务端直接推送(360消息系统目前主要是这种),推拉结合(推送只发通知,推送后根据通知去拉取消息).

     

    拉取的方式不说了,如今并不经常使用了,早期不少是nginx+lua+redis,长轮训,主要问题是开销比较大,时效性也很差,能作的优化策略很少。

     

    直接推送的系统,目前就是360消息系统这种,消息类型是消耗型的,而且对于同一个用户并不容许重复消耗,若是须要多终端重复消耗,须要抽象成不一样用户。

     

    推的好处是实时性好,开销小,直接将消息下发给客户端,不须要客户端走从接入层到存储层主动拉取.

     

    但纯推送模型,有个很大问题,因为系统是异步的,他的时序性没法精确保证。这对于push需求来讲是够用的,但若是复用推送系统作im类型通讯,可能并不合适。

     

    对于严格要求时序性,消息能够重复消耗的系统,目前也都是走推拉结合的模型,就是只使用咱们的推送系统发通知,并附带id等给客户端作拉取的判断策略,客户端根据推送的key,主动从业务服务器拉取消息。而且当主从同步延迟的时候,跟进推送的key作延迟拉取策略。同时也能够经过消息自己的QoS,作纯粹的推送策略,好比一些“正在打字的”低优先级消息,不须要主动拉取了,经过推送直接消耗掉。

     

    哪些因素决定推送系统的效果?

    首先是sdk的完善程度,sdk策略和细节完善度,每每决定了弱网络环境下最终推送质量.

     

    SDK选路策略,最基本的一些策略以下:有些开源服务可能会针对用户hash一个该接入区域的固定ip,实际上在国内环境下不可行,最好分配器(dispatcher)是返回散列的一组,并且端口也要参开,必要时候,客户端告知是retry多组都连不上,返回不一样idc的服务器。由于咱们会常常检测到一些case,同一地区的不一样用户,可能对同一idc内的不一样ip连通性都不同,也出现过同一ip不一样端口连通性不一样,因此用户的选路策略必定要灵活,策略要足够完善.另外在选路过程当中,客户端要对不一样网络状况下的长链接ip作缓存,当网络环境切换时候(wifi、2G、3G),从新请求分配器,缓存不一样网络环境的长链接ip。

     
     

    客户端对于数据心跳和读写超时设置,完善断线检测重连机制

     

    针对不一样网络环境,或者客户端自己消息的活跃程度,心跳要自适应的进行调整并与服务端协商,来保证链路的连通性。而且在弱网络环境下,除了网络切换(wifi切3G)或者读写出错状况,何时从新创建链路也是一个问题。客户端发出的ping包,不一样网络下,多久没有获得响应,认为网络出现问题,从新创建链路须要有个权衡。另外对于不一样网络环境下,读取不一样的消息长度,也要有不一样的容忍时间,不能一刀切。好的心跳和读写超时设置,可让客户端最快的检测到网络问题,从新创建链路,同时在网络抖动状况下也能完成大数据传输。

     

    几个大概重要组件介绍以下:

     

    dispatcher service 根据客户端请求信息,将应网络和区域的长链接服务器的,一组IP传送给客户端。客户端根据返回的IP,创建长链接,链接Room service.

     

    room Service,长链接网关,hold用户链接,并将用户注册进register service,自己也作一些接入安全策略、白名单、IP限制等。

     

    register service 是咱们全局session存储组件,存储和索引用户的相关信息,以供获取和查询。

     

    coordinator service 用来转发用户的上行数据,包括接入方订阅的用户状态信息的回调,另外作须要协调各个组件的异步操做,好比kick用户操做,须要从register拿出其余用户作异步操做.

     

    saver service是存储访问层,承担了对redis和mysql的操做,另外也提供部分业务逻辑相关的内存缓存,好比广播信息的加载能够在saver中进行缓存。另一些策略,好比客户端sdk因为被恶意或者意外修改,每次加载了消息,不回复ack,那服务端就不会删除消息,消息就会被反复加载,造成死循环,能够经过在saver中作策略和判断。(客户端老是不可信的)。

     

    center service 提供给接入方的内部api服务器,好比单播或者广播接口,状态查询接口等一系列api,包括运维和管理的api。

     

    举两个常见例子,了解工做机制:好比发一条单播给一个用户,center先请求Register获取这个用户以前注册的链接通道标识、room实例地址,经过room service下发给长链接Center Service比较重的工做如全网广播,须要把全部的任务分解成一系列的子任务,分发给全部center,而后在全部的子任务里,分别获取在线和离线的全部用户,再批量推到Room Service。一般整个集群在那一瞬间压力很大。

     

    deployd/agent service 用于部署管理各个进程,收集各组件的状态和信息,zookeeper和keeper用于整个系统的配置文件管理和简单调度

     

    结合服务端作策略

     

    另外系统可能结合服务端作一些特殊的策略,好比咱们在选路时候,咱们会将同一个用户尽可能映射到同一个roomservice实例上。断线时,客户端尽可能对上次链接成功的地址进行重试。主要是方便服务端作闪断状况下策略,会暂存用户闪断时实例上的信息,从新连入的时候,作单实例内的迁移,减小延时与加载开销.

     

    客户端保活策略

     

    不少创业公司愿意从新搭建一套push系统,确实不难实现,其实在协议完备状况下(最简单就是客户端不回ack不清数据),服务端会保证消息是不丢的。但问题是为何在消息有效期内,到达率上不去?每每由于本身app的pushservice存活能力不高。选用云平台或者大厂的,每每sdk会作一些保活策略,好比和其余app共生,互相唤醒,这也是云平台的pushservice更有保障缘由。我相信不少云平台旗下的sdk,多个使用一样sdk的app,为了实现服务存活,是能够互相唤醒和保证活跃的。另外如今push sdk自己是单链接,多app复用的,这为sdk实现,增长了新的挑战。

     

    综上,对我来讲,选择推送平台,优先会考虑客户端sdk的完善程度。对于服务端,选择条件稍微简单,要求部署接入点(IDC)越要多,配合精细的选路策略,效果越有保证,至于想知道哪些云服务有多少点,这个群里来自各地的小伙伴们,能够合伙测测。

     
     

    当时出现问题,如今总结起来,大概如下几点

     

    1.散落在协程里的I/O,Buffer和对象不复用。

     

    当时(12年)因为对go的gc效率理解有限,比较奔放,程序里大量short live的协程,对内通讯的不少io操做,因为不想阻塞主循环逻辑或者须要及时响应的逻辑,经过单独go协程来实现异步。这回会gc带来不少负担。

    针对这个问题,应尽可能控制协程建立,对于长链接这种应用,自己已经有几百万并发协程状况下,不少状况不必在各个并发协程内部作异步io,由于程序的并行度是有限,理论上作协程内作阻塞操做是没问题。

    若是有些须要异步执行,好比若是不异步执行,影响对用户心跳或者等待response没法响应,最好经过一个任务池,和一组常驻协程,来消耗,处理结果,经过channel再传回调用方。使用任务池还有额外的好处,能够对请求进行打包处理,提升吞吐量,而且能够加入控量策略.

     

    2.网络环境很差引发激增

     

    go协程相比较以往高并发程序,若是作很差流控,会引发协程数量激增。早期的时候也会发现,时不时有部分主机内存会远远大于其余服务器,但发现时候,全部主要profiling参数都正常了。

     

    后来发现,通讯较多系统中,网络抖动阻塞是不可免的(即便是内网),对外不停accept接受新请求,但执行过程当中,因为对内通讯阻塞,大量协程被建立,业务协程等待通讯结果没有释放,每每瞬时会迎来协程暴涨。但这些内存在系统稳定后,virt和res都并没能完全释放,降低后,维持高位。

     

    处理这种状况,须要增长一些流控策略,流控策略能够选择在rpc库来作,或者上面说的任务池来作,其实我感受放在任务池里作更合理些,毕竟rpc通讯库能够作读写数据的限流,但它并不清楚具体的限流策略,究竟是重试仍是日志仍是缓存到指定队列。任务池自己就是业务逻辑相关的,它清楚针对不一样的接口须要的流控限制策略。

     

    3.低效和开销大的rpc框架

     

    早期rpc通讯框架比较简单,对内通讯时候使用的也是短链接。这原本短链接开销和性能瓶颈超出咱们预期,短链接io效率是低一些,但端口资源够,自己吞吐能够知足须要,用是没问题的,不少分层的系统,也有http短链接对内进行请求的

     

    但早期go版本,这样写程序,在必定量级状况,是支撑不住的。短链接大量临时对象和临时buffer建立,在本已经百万协程的程序中,是没法承受的。因此后续咱们对咱们的rpc框架做了两次调整。

     

    第二版的rpc框架,使用了链接池,经过长链接对内进行通讯(复用的资源包括client和server的:编解码Buffer、Request/response),大大改善了性能。

     

    但这种在一次request和response仍是占用链接的,若是网络情况ok状况下,这不是问题,足够知足须要了,但试想一个room实例要与后面的数百个的register,coordinator,saver,center,keeper实例进行通讯,须要创建大量的常驻链接,每一个目标机几十个链接,也有数千个链接被占用。

     

    非持续抖动时候(持续逗开多少无解),或者有延迟较高的请求时候,若是针对目标ip链接开少了,会有瞬时大量请求阻塞,链接没法获得充分利用。第三版增长了Pipeline操做,Pipeline会带来一些额外的开销,利用tcp的全双特性,以尽可能少的链接完成对各个服务集群的rpc调用。

     

    4.Gc时间过长

     

    Go的Gc仍旧在持续改善中,大量对象和buffer建立,仍旧会给gc带来很大负担,尤为一个占用了25G左右的程序。以前go team的大咖邮件也告知咱们,将来会让使用协程的成本更低,理论上不须要在应用层作更多的策略来缓解gc.

     

    改善方式,一种是多实例的拆分,若是公司没有端口限制,能够很快部署大量实例,减小gc时长,最直接方法。不过对于360来讲,外网一般只能使用80和433。所以常规上只能开启两个实例。固然不少人给我建议可否使用SO_REUSEPORT,不过咱们内核版本确实比较低,并无实践过。

     

    另外可否模仿nginx,fork多个进程监控一样端口,至少咱们目前没有这样作,主要对于咱们目前进程管理上,仍是独立的运行的,对外监听不一样端口程序,还有配套的内部通讯和管理端口,实例管理和升级上要作调整。

     

    解决gc的另两个手段,是内存池和对象池,不过最好作仔细评估和测试,内存池、对象池使用,也须要对于代码可读性与总体效率进行权衡。

     

    这种程序必定状况下会下降并行度,由于用池内资源必定要加互斥锁或者原子操做作CAS,一般原子操做实测要更快一些。CAS能够理解为可操做的更细行为粒度的锁(能够作更多CAS策略,放弃运行,防止忙等)。这种方式带来的问题是,程序的可读性会愈来愈像C语言,每次要malloc,各地方用完后要free,对于对象池free以前要reset,我曾经在应用层尝试作了一个分层次结构的“无锁队列”

    上图左边的数组其实是一个列表,这个列表按大小将内存分块,而后使用atomic操做进行CAS。但实际要看测试数据了,池技术能够明显减小临时对象和内存的申请和释放,gc时间会减小,但加锁带来的并行度的下降,是否能给一段时间内的总体吞吐量带来提高,要作测试和权衡…

     

    在咱们消息系统,实际上后续去除了部分这种黑科技,试想在百万个协程里面作自旋操做申请复用的buffer和对象,开销会很大,尤为在协程对线程多对多模型状况下,更依赖于golang自己调度策略,除非我对池增长更多的策略处理,减小忙等,感受是在把runtime作的事情,在应用层很是不优雅的实现。广泛使用开销理论就大于收益。

     

    但对于rpc库或者codec库,任务池内部,这些开定量协程,集中处理数据的区域,能够尝试改造~

     

    对于有些固定对象复用,好比固定的心跳包什么的,能够考虑使用全局一些对象,进行复用,针对应用层数据,具体设计对象池,在部分环节去复用,可能比这种无差异的设计一个通用池更能进行效果评估.

    消息系统的运维及测试

    下面介绍消息系统的架构迭代和一些迭代经验,因为以前在其余地方有过度享,后面的会给出相关连接,下面实际作个简单介绍,感兴趣能够去连接里面看

     

    架构迭代~根据业务和集群的拆分,能解决部分灰度部署上线测试,减小点对点通讯和广播通讯不一样产品的相互影响,针对特定的功能作独立的优化.

     

    消息系统架构和集群拆分,最基本的是拆分多实例,其次是按照业务类型对资源占用状况分类,按用户接入网络和对idc布点要求分类(目前没有条件,全部的产品都部署到所有idc)

     


    唐福林/1.5 雪球在股市风暴下的高可用架构改造分享.46
    1.5.1 雪球公司的介绍46
    1.5.2 雪球当前整体架构47
    1.5.3 雪球架构优化历程48
    1.5.4 关于架构优化的总结和感想.53
    1.5.5 疑问与解惑.54

    四. 聊聊关于架构优化的一些总结和感想

     

    在各类场合常常据说的架构优化,通常都是优化某一个具体的业务模块,将性能优化到极致。而在雪球,咱们作的架构优化更多的是从问题出发,解决实际问题,解决到能够接受的程度便可。可能你们看起来会以为很凌乱,并且每一个事情单独拎出来好像都不是什么大事。

     

    咱们在对一个大服务作架构优化时,通常是往深刻的本质进行挖掘;当咱们面对一堆架构各异的小服务时,“架构优化”的含义实际上是有一些不同的。大部分时候,咱们并不须要(也没有办法)深刻到小服务的最底层进行优化,而是去掉或者优化原来明显不合理的地方就能够了。

     

    在快速迭代的创业公司,咱们可能不会针对某一个服务作很完善的架构设计和代码实现,当出现各类问题时,也不会去追求极致的优化,而是以解决瓶颈问题为先

     

    即便咱们经历过一回将 snowball 拆分服务化的过程,但当咱们从新上一个新的业务时,咱们依然选择将它作成一个大一统的服务。只是这一次,咱们会提早定义好每一个模块的 service 接口,为之后可能的服务化铺好路。

     

    在创业公司里,重写是不能接受的;大的重构,从时间和人力投入上看,通常也是没法承担的。而“裱糊匠”式作法,哪里有性能问题就加机器,加缓存,加数据库,有可用性问题就加剧试,加log,出故障就加流程,加测试,这也不是雪球团队工做方式。咱们通常都采用最小改动的方式,即,准肯定义问题,定位问题根源,找到问题本质,制定最佳方案,以最小的改动代价,将问题解决到可接受的范围内

     

    咱们如今正在全部的地方强推3个数据指标:qps,p99,error rate。每一个技术人员对本身负责的服务,必定要有最基本的数据指标意识。数字,是发现问题,定位根源,找到本质的最重要的依赖条件。没有之一。

     

    咱们的原则:保持技术栈的一致性和简单性,有节制的尝试新技术,保持全部线上服务依赖的技术可控,简单来讲,能 hold 住

    能用cache的地方毫不用db,能异步的地方,毫不同步。俗称的:吃一堑,长一智。

     

    特事特办:业务在发展,需求在变化,实现方式也须要跟着变化。简单的来讲:遗留系统的优化,最佳方案就是砍需求,呵呵

    当前,雪球内部正在推行每一个模块的方案和代码实现的 review,在 review 过程当中,我通常是这样要求的:

     

    技术方案:

     

    • 20倍设计,10倍实现,3倍部署

    • 扩展性:凡事留一线,之后好相见

     

    技术实现:

     

    • DevOps:上线后仍是你本身维护的项目,实现的时候记得考虑各类出错的处理

    • 用户投诉的时候须要你去解释,实现的时候注意各类边界和异常

    • 快速实现,不是“随便实现”,万一火了呢:性能,方便扩容

     
       

    麦俊生/1.6 亿级短视频社交美拍架构实战591.6.1 短视频市场的发展591.6.2 美拍的发展.601.6.3 短视频所面临的架构问题611.6.4 为支持亿级用户,美拍架构所作的一些改进621.6.5 后续发展68刘道儒/1.7 微博“异地多活”部署经验谈691.7.1 微博异地多活建设历程691.7.2 微博异地多活面临的挑战701.7.3 异地多活的最佳实践.731.7.4 异地多活的新方向74孙宇聪/1.8 来自Google 的高可用架构理念与实践751.8.1 决定可用性的两大因素761.8.2 高可用性方案771.8.3 可用性7 级图表801.8.4 疑问与解惑.81那 谁/1.9 深刻理解同步/异步与阻塞/非阻塞区别841.9.1 同步与异步.841.9.2 阻塞与非阻塞851.9.3 与多路复用I/O 的联系86第2 章 高可用架构原理与分布式实践.88黄东旭/2.1 Codis 做者细说分布式Redis 架构设计882.1.1 Redis、Redis Cluster 和Codis882.1.2 咱们更爱一致性902.1.3 Codis 在生产环境中的使用经验和坑912.1.4 分布式数据库和分布式架构.942.1.5 疑问与解惑.95霍泰稳/2.2 给你介绍一个不同的硅谷.982.2.1 Uber .982.2.2 Coursera.992.2.3 Airbnb1022.2.4 硅谷行带给个人一些影响1062.2.5 疑问与解惑106金自翔/2.3 解耦的艺术——大型互联网业务系统的插件化改造1102.3.1 插件化.1102.3.2 如何处理用户交互1152.3.3 如何处理数据.1152.3.4 总结116沈 剑/2.4 从零开始搭建高可用IM 系统1172.4.1 什么是IM1172.4.2 协议设计1182.4.3 WEB 聊天室.1222.4.4 IM 典型业务场景1262.4.5 疑问与解惑126陈宗志/2.5 360 分布式存储系统Bada 的架构设计和应用.1292.5.1 主要应用场景.1292.5.2 总体架构1302.5.3 主要模块1312.5.4 数据分布策略.1322.5.5 请求流程1332.5.6 多机房架构1342.5.7 FAQ1382.5.8 疑问与解惑139张 亮/2.6 新一代分布式任务调度框架:当当Elastic-Job 开源项目的10 项特性1432.6.1 为何须要做业(定时任务).1432.6.2 当当以前使用的做业系统1442.6.3 Elastic-Job 的来历.1442.6.4 Elastic-Job 包含的功能1452.6.5 Elastic-Job 的部署和使用.1462.6.6 对开源产品的开发理念.1472.6.7 将来展望1482.6.8 疑问与解惑149付海军/2.7 互联网DSP 广告系统架构及关键技术解析1522.7.1 优秀DSP 系统的特色1522.7.2 程序化购买的特色1532.7.3 在线广告的核心问题1562.7.4 在线广告的挑战.1562.7.5 DSP 系统架构.1572.7.6 RTB 投放引擎的架构.1582.7.7 DMP1602.7.8 广告系统DMP 数据处理的架构.1602.7.9 用户画像的方法.1622.7.10 广告行业的反做弊.1652.7.11 P2P 流量互刷1662.7.12 CPS 引流做弊1672.7.13 疑问与解惑168王卫华/2.8 亿级规模的Elasticsearch 优化实战1702.8.1 索引性能(Index Performance) .1702.8.2 查询性能(Query Perofrmance) 1712.8.3 其余1732.8.4 疑问与解惑174杨卫华/2.9 微博分布式存储考试题:案例讲解及做业精选1792.9.1 访问场景1792.9.2 设计1802.9.3 sharding 策略1802.9.4 案例精选181李 凯/2.10 架构师须要了解的Paxos 原理、历程及实战.1842.10.1 数据库高可用性难题1842.10.2 Paxos 协议简单回顾.1852.10.3 Basic Paxos 同步日志的理论模型1862.10.4 Multi Paxos 的实际应用.1872.10.5 依赖时钟偏差的变种Paxos 选主协议简单分析1902.10.6 疑问与解惑191温 铭/2.11 OpenResty 的如今和将来1932.11.1 OpenResty 是什么,适合什么场景下使用.1932.11.2 某安全公司服务端技术选型的标准1942.11.3 如何在项目中引入新技术.1962.11.4 如何入门以及学习的正确方法1972.11.5 OpenResty 中的测试和调试.1992.11.6 NginScript 是否会替代OpenResty2012.11.7 将来重点解决的问题和新增特性.2022.11.8 开源社区建设2032.11.9 疑问与解惑.203第3 章 电商架构热点专题.205张开涛/3.1 亿级商品详情页架构演进技术解密.2053.1.1 商品详情页2053.1.2 商品详情页发展史2093.1.3 遇到的一些问题和解决方案2203.1.4 总结2283.1.5 疑问与解惑229杨 超/3.2 大促系统全流量压测及稳定性保证——京东交易架构.2323.2.1 交易系统的三个阶段2323.2.2 交易系统的三层结构2333.2.3 交易系统的访问特征2343.2.4 应对大促的第1 步:全链路全流量线上压测.2343.2.5 应对大促的第2 步:根据压力表现进行调优.2373.2.6 异步和异构2403.2.7 应对大促的第3 步:分流与限流2423.2.8 应对大促的第4 步:容灾降级.2443.2.9 应对大促的第5 步:完善监控.2453.2.10 疑问与解惑246吕 毅/3.3 秒杀系统架构解密与防刷设计.2483.3.1 抢购业务介绍.2483.3.2 具体抢购项目中的设计.2493.3.3 如何解耦先后端压力2503.3.4 如何保证商品库的库存可靠2523.3.5 如何与第三方多方对帐.2543.3.6 项目总结2553.3.7 疑问与解惑255王富平/3.4 Lambda 架构与推荐在电商网站实践.2573.4.1 Lambda 架构2573.4.2 1 号店推荐系统实践2603.4.3 Lambda 的将来2623.4.4 思考2633.4.5 疑问与解惑263杨 硕/3.5 某公司线上真实流量压测工具构建.2653.5.1 为何要开发一个通用的压测工具2653.5.2 常见的压测工具.2663.5.3 构建本身的压测工具2663.5.4 疑问与解惑271第4 章 容器与云计算.273陈 飞/4.1 微博基于Docker 容器的混合云迁移实战.2734.1.1 为何要采用混合云的架构2734.1.2 跨云的资源管理与调度.2754.1.3 容器的编排与服务发现.2784.1.4 混合云监控体系.2844.1.5 前进路上遇到的那些坑.2864.1.6 疑问与解惑286高 磊/4.2 互联网金融创业公司Docker 实践2874.2.1 背景介绍2874.2.2 容器选型2874.2.3 应用迁移2884.2.4 弹性扩容2914.2.5 将来规划2954.2.6 疑问与解惑295高永超/4.3 使用开源Calico 构建Docker 多租户网络.2974.3.1 PaaS 平台的网络需求.2974.3.2 使用Calico 实现Docker 的跨服务器通信.2984.3.3 利用Profile 实现ACL3014.3.4 性能测试3064.3.5 Calico 的发展3084.3.6 疑问与解惑309彭哲夫/4.4 解析Docker 在芒果TV 的实践之路3104.4.1 豆瓣时期3104.4.2 芒果TV 的Nebulium Engine .3114.4.3 Project Eru .3124.4.4 细节3134.4.5 网络3144.4.6 存储3154.4.7 Scale3164.4.8 资源分配和集群调度3164.4.9 服务发现和安全.3174.4.10 实例3174.4.11 总结3184.4.12 疑问与解惑318王关胜/4.5 微博基于Docker 的混合云平台设计与实践3234.5.1 微博的业务场景及混合云背景.3234.5.2 三大基础设施助力微博混合云.3264.5.3 微博混合云DCP 系统设计核心:自动化、弹性调度3284.5.4 引入阿里云做为第3 机房,实现弹性调度架构3304.5.5 大规模集群操做自动化.3314.5.6 不怕峰值事件.332第5 章 运维保障333王 康/5.1 360 如何用QConf 搞定两万以上服务器的配置管理.3335.1.1 设计初衷3335.1.2 总体认识3345.1.3 架构介绍3355.1.4 QConf 服务端3365.1.5 QConf 客户端3365.1.6 QConf 管理端3405.1.7 其余3415.1.8 疑问与解惑343尤 勇/5.2 深度剖析开源分布式监控CAT3475.2.1 背景介绍3475.2.2 总体设计3485.2.3 客户端设计3495.2.4 服务端设计3525.2.5 总结感悟357杨尚刚/5.3 单表60 亿记录等大数据场景的MySQL 优化和运维之道3595.3.1 前言3595.3.2 数据库开发规范.3605.3.3 数据库运维规范.3635.3.4 性能优化3685.3.5 疑问与解惑375秦 迪/5.4 微博在大规模、高负载系统问题排查方法3795.4.1 背景3795.4.2 排查方法及线索.3795.4.3 总结3845.4.4 疑问与解惑385秦 迪/5.5 系统运维之为何每一个团队存在大量烂代码3875.5.1 写烂代码很容易.3875.5.2 烂代码终究是烂代码3885.5.3 重构不是万能药.3925.5.4 写好代码很难.3935.5.5 悲观的结语394秦 迪/5.6 系统运维之评价代码优劣的方法3955.6.1 什么是好代码.3955.6.2 结语4035.6.3 参考阅读403秦 迪/5.7 系统运维之如何应对烂代码4045.7.1 改善可维护性.4045.7.2 改善性能与健壮性4095.7.3 改善生存环境.4125.7.4 我的感想414第6 章 大数据与数据库415王 劲/6.1 某音乐公司的大数据实践.4156.1.1 什么是大数据.4156.1.2 某音乐公司大数据技术架构4186.1.3 在大数据平台重构过程当中踩过的坑4256.1.4 后续的持续改进.430王新春/6.2 实时计算在点评.4316.2.1 实时计算在点评的使用场景4316.2.2 实时计算在业界的使用场景4326.2.3 点评如何构建实时计算平台4336.2.4 Storm 基础知识简单介绍.4346.2.5 如何保证业务运行的可靠性4366.2.6 Storm 使用经验分享4386.2.7 关于计算框架的后续想法4426.2.8 疑问与解惑442王卫华/6.3 百姓网Elasticsearch 2.x 升级之路.4466.3.1 Elasticsearch 2.x 变化4466.3.2 升级之路4486.3.3 优化或建议4516.3.4 百姓之道4526.3.5 后话:Elasticsearch 5.04536.3.6 升级2.x 版本成功,5.x 版本还会远吗454董西成 张虔熙/6.4 Hadoop、HBase 年度回顾4576.4.1 Hadoop 2015 技术发展4576.4.2 HBase 2015 年技术发展4606.4.3 疑问与解惑466常 雷/6.5 解密Apache HAWQ——功能强大的SQL-on-Hadoop 引擎.4696.5.1 HAWQ 基本介绍4696.5.2 Apache HAWQ 系统架构.4726.5.3 HAWQ 中短时间规划.4796.5.4 贡献到Apache HAWQ 社区4796.5.5 疑问与解惑480萧少聪/6.6 PostgresSQL HA 高可用架构实战.4826.6.1 PostgreSQL 背景介绍.4826.6.2 在PostgreSQL 下如何实现数据复制技术的HA 高可用集群4836.6.3 Corosync+Pacemaker MS 模式介绍4846.6.4 Corosync+Pacemaker M/S 环境配置4856.6.5 Corosync+Pacemaker HA 基础配置4886.6.5 PostgreSQL Sync 模式当前的问题4926.6.6 疑问与解惑492王晶昱/6.7 从NoSQL 历史看将来.4956.7.1 前言4956.7.2 1970 年:We have no SQL4966.7.3 1980 年:Know SQL 4976.7.4 2000 年:No SQL .5026.7.5 2005 年:不只仅是SQL 5046.7.6 2013 年:No,SQL .5056.7.7 阿里的技术选择.5056.7.8 疑问与解惑506杨尚刚/6.8 MySQL 5.7 新特性大全和将来展望.5086.8.1 提升运维效率的特性5086.8.2 优化器Server 层改进.5116.8.3 InnoDB 层优化5136.8.4 将来发展5176.8.5 运维经验总结.5186.8.6 疑问与解惑519谭 政/6.9 大数据盘点之Spark 篇5216.9.1 Spark 的特性以及功能5216.9.2 Spark 在Hulu 的实践.5256.9.3 Spark 将来的发展趋势5286.9.4 参考文章5306.9.5 疑问与解惑530萧少聪/6.10 从Postgres 95 到PostgreSQL 9.5:新版亮眼特性5326.10.1 Postgres 95 介绍5326.10.2 PostgresSQL 版本发展历史5336.10.3 PostgresSQL 9.5 的亮眼特性5346.10.4 PostgresSQL 还能够作什么5446.10.5 疑问与解惑547毕洪宇/6.11 MongoDB 2015 回顾:全新里程碑式的WiredTiger 存储引擎5516.11.1 存储引擎的发展5516.11.2 复制集改进.5556.11.3 自动分片机制5566.11.4 其余新特性介绍5566.11.5 疑问与解惑.558王晓伟/6.12 基于Xapian 的垂直搜索引擎的构建分析5616.12.1 垂直搜索的应用场景5616.12.2 技术选型.5636.12.3 垂直搜索的引擎架构5646.12.4 垂直搜索技术和业务细节.5666.12.5 疑问与解惑568第7 章 安全与网络572郭 伟/7.1 揭秘DDoS 防御——腾讯云大禹系统5727.1.1 有关DDoS 简介的问答.5747.1.2 有关大禹系统简介的问答5757.1.3 有关大禹系统硬件防御能力的问答5767.1.4 有关算法设计的问答5777.1.5 大禹和其余产品、技术的区别.578冯 磊 赵星宇/7.2 App 域名劫持之DNS 高可用——开源版HttpDNS 方案详解5807.2.1 HttpDNSLib 库组成.5817.2.2 HttpDNS 交互流程5827.2.3 代码结构5837.2.4 开发过程当中的一些问题及应对.5867.2.5 疑问与解惑593马 涛/7.3 CDN 对流媒体和应用分发的支持及优化5957.3.1 CDN 系统工做原理.5957.3.2 网络分发过程当中ISP 的影响6027.3.3 防盗链.6037.3.4 内容分发系统的问题和应对思路6047.3.5 P2P 穿墙打洞6077.3.6 疑问与解惑609马 涛/7.4 HTTPS 环境使用第三方CDN 的证书难题与最佳实践611蒋海滔/7.5 互联网主要安全威胁分析及应对方案6137.5.1 互联网Web 应用面临的主要威胁6137.5.2 威胁应对方案.6167.5.3 疑问与解惑624