分布式服务杂谈

要点有如下几项:

1、垂直分层:DNS层、跨机房部署、LVS+Nginx负载均衡,vanish+共享存储实现动静分离,Nginx后挂载N台服务器集群,服务器集群后挂载微服务化、微服务后挂载数据库分库分表+消息队列+任务调度,最后端挂载数据集群负责数据的统一归档+流计算+异步批处理

2、水平分区:根据业务划分业务线,每个业务线中设计分区键,根据userNo设计用户隔离,根据IP地址设计地区隔离,根据用户级别设计级别隔离,根据操作日期设计时间隔离,根据关键key进行hash散列,然后考虑一下分区的扩容、缩容、灾备、监控

3、数据同步,跨机房跨集群的困难点在于数据同步,有三种做法:

3.1)不同步,任由各子集群在自己的业务范围内运行

3.2)汇总集群,建立一个统一的数据汇总集群(如Hadoop\Spark\Kylin等),将数据汇总到统一的大数据集群中,再进行统计、汇总、运算等。缺点是会有时间差,短须5分钟,长须一天以上

3.3)远程数据同步,通过开源框架实现多个数据库的同步,例如阿里的otter,底层为canal,模拟mysql的从库,实现日志解析并数据库入库,时间差较短,如果网络没有太大问题,可在秒级完成数据同步。数据同步冲突算法有两种:单向回环补救、时间交集补救。一般推荐使用单向回环补救,即:如果发现数据库A与数据库B的同步时间差大于某个数值,则根据pk查询最新记录同步到数据库中。而另一种算法时间交集补救,是根据“时间交集”的定义,获得双方数据库的“时间交叉的操作”清单,然后根据此清单执行单向回环补救。此方法缺点为:a)开源版本中仅有单向回环补救;b)只支持mysql->mysql同步或者mysql->oracle同步。

集齐以上三件,基本上百万级并发就轻松搞定了。然后需要注意一些细节:

1)集群与集群之间要实现从入口开始的严格隔离,即DNS层->LVS层->Nginx层完全隔离

2)数据库的链接数是重要资源,一个mysql数据库可以提供1000链接,也就是说,按照50链接/每机器来计算,最多链接20个实例,硬上一下超不过30台。因此数据库层的分库分表一定要彻彻底底的分开。子集群之间不能互相链接数据库。

3)一些关键业务可以在缓存中操作,建议采用redis缓存。而memcache死机后数据丢失,mongodb功能尚不完善。redis的安全机制一定要做好,千万不能丢数据。缓存到数据库的存储可以采用计数形式,每隔N次操作存一次数据库,可以线性降低数据库压力

4)数据库只使用简单的存取功能,所有业务功能在代码层实现,DBA推荐的分区、分存储、存储过程等功能一般在数据仓库中是有用的,而在实时计算系统中,千万不要采用。否则你会看到你们几百人的开发团队等待一个DBA给你们排期的情况。

5)前端可以做一些小的手段,例如抽奖活动,可以在页面js中直接告诉用户未中奖,而并不通知后台,此为“基础不中奖率”,可以直接过滤掉90%以上的流量。(此功能请与产品团队好好沟通,从性价比上讲,这种小手段不提倡,但是性价比极高。)

6)消息队列系统建议采用一些堆积能力较强的系统,如:rocketmq,rabbit等,建议rocketmq,消息堆积能力之强,单机堆积上亿条。

7)日志系统建议kafka,日志系统之后可以增加storm,hdfs,logstash等配套设施

8)网卡流量问题需要严重关注,经常出现的问题是:在某个活动之间,redis网卡流量打满,导致redis无法访问,整个业务暂停。需要网络部门对公司内部的服务器路由有准确估算,出现分值之后可以妥善定位问题并修复,日常工作中也要做好规划,提前做好准备。

9)老生常谈的:断路器、限流、自动降级。断路器是指在RPC的客户端中实现如下功能:如果发现该断路器访问服务端在10秒内访问超过50次且失败率高于50%,则中断该断路器的访问10秒钟,以保护下游系统。自动降级就是:如果发生问题,自动切换到备用程序上,如报错、如访问redis失败改访问DB等。限流就是在RPC的服务端中实现如下功能:对每个IP、每个token进行限制,通过令牌桶算法,每个时间段只允许指定数量的服务通过,否则就拒绝服务调用。一般断路器使用hystrix,自动降级可以自行实现,也可以用hystrix的配套设施实现,限流比较简单自行实现即可。

 

这么一套下来,大概得三四百人,时间得四五年吧,估算一下:

工资成本两个亿

服务器预算一个亿

网络流量费、电费、机架费、安全监测费、域名费用、第三方采购费用......

大致可以这么说:如果一家公司计划三年内投入五个亿,还计算搞一番事业出来的,这套框架就够了,包你从QPS500到QPS10000到QPS1亿稳定运行。


但本文主旨不是要告诉你如何搭建一个亿万计的高并发系统,我的意思是:现在高并发技术烂大街了,每当我看到一个人和我吹嘘高并发多么多么牛,我心中总是泛起一丝怜悯。

想想战争年代的发报员

想想几十年前的司机

想想十年前的站长

想想五年前的国产操作系统

想想三年前的移动端开发

想想一年前的docker

。。。。。。

高并发只是一种类似的技术:使用场景少,价格高昂,好比屠龙之技,龙就那么几条,还都差不多被砍死了。随着相关资料的泛滥,将来它会是一门“出入江湖必备的手艺”,如太祖长拳一般的泛滥,不值一文。

作为一个天天和高并发打交道的程序员,我并不觉得一定要有高并发实际项目经验才能做高并发,有些完全没有实际高并发经验的人,没准上手也能做的很好。但也很有可能上来就塌了。高并发只是一个不确定的结果,并不是过程。为什么我说是不确定呢?在来自全人类的高并发访问面前,一切都有可能发生,所以我们经常能看到顶级网站的颤抖。我把我觉得有用的东西汇集到一起,希望能对大家有帮助。

首先,我觉得基础知识非常重要,这包括算法,操作系统,jvm,数据库,缓存,多线程等等,其实这都是独立而又关联的知识。书本里都有,但理论要结合实际,一定要联系到具体的技术才会有用。但也别迷信任何技术,比如说使用了netty就能比谁谁谁快几十倍,但这有两个前提,一个是netty适合你的应用场景,另一个是你用netty用的合理。也别只痴迷于框架,框架只会挡住你的眼睛,让你觉得什么都不重要。大并发面前,没一个框架靠得住,靠得住的只有人,是人来根据具体的应用场景,使用各种知识去解决具体的问题。

一个后端程序员最重要的技能是分布式系统设计,这是经验和知识的结合,或者说就是用前面提到的基础来搭积木。编程语言是不重要的,但有那么几个语言在高并发应用方面积累了非常多的宝贵经验,比如说java,scala还有新兴的go。

这里最常见的就是如何分片sharding和负载均衡load balancer。为什么要分片和负载均衡呢? 因为一台机器你再怎么玩,能力也是有限的。很多人都知道都知道更大的并发需要更多的服务器,这么多的服务器怎么分工,就是分片和负载均衡。这听起来还是挺容易的,做起来也不难。

有时候你的分布式系统很可能加不了那么多服务器,这就是所谓的scalability,这是我们在项目伊始就要多加注意的地方。但这东西有个平衡,高的scalability不是没有代价的。我以前给人家讲课的时候,常讲一个例子,如果你设计一个自家厨房,你肯定只设计一个洗碗的水池对不对?平时绝对是够用的,但是如果你有一天请20个朋友来你家吃饭,吃饭大家围着桌子一起吃非常快,但你发现洗碗就scale不上去了,派再多人洗碗也没用,最多同时只能一个人在洗碗,这就成为你家接待能力的瓶颈。但家里厨房并不是为接待20+个朋友设计的,搞太多水池是个累赘。这就需要权衡,没有一定对的设计。

所以并没有一种高并发设计可以打遍天下无敌手,google, twitter, amazon, facebook, linkedin都有自己的应用场景,有自己的实际需要,有自己的权衡,有自己的技术特点。有一得就必有一失,比如说google和uber使用go来解决起自身的特殊需要和已经产生的问题,但是go对你的团队来说可能仅仅是个略显丑陋的普通语言。你去照搬人家微服务的设计,很可能还不如老老实实用个spring mvc + mysql

“这里并没有什么所谓的顶点,我们还仍然愿意为此挥拳“

------我忘了我在哪里看到了

所以我们去了解我们自己系统的特点,选择对应的技术,明白当前技术的得失。

高并发和scalability还不能离开高可用,你搞5w台服务器,但只要坏一台就全部服务都受影响肯定是不行的。你想如果1台服务器的可用性是99%,那如果你有100台,它们在一起每台都不坏的可用性就只有99%^100, 这个值只有36.6%。也就是说如果你有个100台机器的机房,每年大半时间都有机器在出问题。单纯的冗余并不能解决问题,如果有些服务坏掉或者重启,你需要能有一些应对和调整的策略,你需要让别的服务器知道哪些下游服务器可用,哪些已经挂了。这有很多的搞法,大家可以看看zookeeper。但像zookeeper这样的技术也不能过度使用,有些朋友把啥都往zookeeper里放,造成zookeeper成了系统的瓶颈,这就反而不美了。

这有还很多细节,比如说id怎么生成,你用一个mysql自增长的整数就会影响并发的能力,uuid生成也没那么简单,也要根据实际情况调整。比如说你的数据怎么sharding,以后怎么扩容,可以看看一致性哈希,再结合前面id算法,可以给你带来很多思考。然后跨多个数据中心怎么办,如果是一个可写其他只读,那我怎么知道去哪个数据中心写,其实还是可以做在那个id算法里。这些我觉得也可以自学,网上公开的资料很多。

现在的高并发服务不单单是线上的服务,还包括很多线下的服务,比如说大数据,这个也是不能忽视的部分。数据处理又根据你的需要可以是实时的,实时的可以使用storm, twitter有一个新的实现heron,有更合理的架构,而且和storm api兼容。如果不是实时的,选择就更多了。

很多人可能会比较在意GC的设置,其实GC并不直接影响你系统的并发能力,它可能会影响到你系统的吞吐量和访问延时之间的关系,而且其实近年来jvm和go的默认GC设置已经很难让其成为系统的瓶颈了。

最后才是实操经验,其实这主要让猎头和hr觉得你行,因为你干过。但你具体行不行技术面试一聊就知道了,再好的公司也不是各个都行。国内做得好的可以多看看阿里、头条等,但我不知道他们具体并发多少。如果你前面那些基础好,去阿里和头条不会太难,去一个核心点的组,就接触到了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值