暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何设计一套分布式系统

杨遥 2020-01-19
314

要设计一套分布式系统是非常复杂的,也需要非常多的知识积累,但是做技术的永远不能等到要用的时候再去学。可能就有那么一天,领导突然把你交到办公室对你说,小王八,公司发展迅速,用户量已经达到了5000万,现在需要设计一套分布式系统来做支撑。


假设你之前对于分布式系统不了解,连设计方案都拿不出来,是不是一头雾水,浪费了小王八这个称号。如果你能考虑到一下内容,那么这个称号就非你莫属啦[旺柴]


项目梳理


系统的高峰时间段可能也就集中在每天的几小时,不同的业务需求高峰期间肯定是不同的。我们这里假设我们的系统高峰时期存在中午的12点到下午1点,晚上7点到8点,高峰期也就2小时。


服务器预估


5000万的用户量,用二八法则计算出1000万的用户可能同时在线。假设1000万的用户对我们的系统每秒的操作请求有3个,那么就对应了3000万次请求。那么我们就可以计算出30000000/2/60/60约等于4200次请求/秒,而这里只是我们粗略计算的峰值,而真正的高峰期可能会2-3倍,我们以3倍来计算,那么会12600次/秒的请求数。而一台tomcat服务器默认最大线程数是200,我们假设一台能支撑500的请求数,那么就需要12600/500=22台服务器


数据库预估


请求数是12600次/秒,那么可能我们的系统需要的可能就是一个请求设计到多个和数据库打交道的。比如淘宝的查询订单,是不是先查用户,再查订单,可能中间还有其他复杂的链路。我们就以一次请求对应2次数据库交互,那么对应25200次/秒。而我们的生产数据库大多数是16C 32G,假设我们允许一台数据库每秒能处理4000-5000个,我们以5000做计算,那么就是25200/5000=6台,如果只是这样计算的话是需要6台数据库。


我们再来细分一下,25200次不能每次都是增删改吧,大多数的系统还是查询比较多。同样二八法则一分,就有5040个增删改,20160次的查询操作。就算是查询我们也需要分出5个数据库做读写分离吧。那么我们现在的做法就是一个主mysql,5个从。我们都知道数据库的代价是很高的,我们再分一下。


详细评估


20160次的查询,其实60%-80%都是可以做缓存的,此时我们引入redis做缓存,redis的读写效率就很高了,官方测试每秒的查询可以达到11万/秒,那么可以轻松的解决我们目前的问题。假设80%做了缓存的话,那么就只有4000多一点真正去数据库查询,那么此时的方案就是一个mysql主,一个mysql从,加上redis做缓存就能支撑。刚刚我们也说了假设数据库处理是5000,你的写库已经5040的,你怕数据库撑不住挂掉怎么办,此时你可以引入消息中间件MQ来削峰处理,降低mysql的处理量,排队处理,那么我们的系统就可以轻松抗住了。


那么此时我们的系统就需要的是,一个redis集群,一个master mysql,一个slave mysql,一个消息中间件就能撑住我们的5000万用户的系统,当然上面也说了不同的业务需求对应着不同的高峰期时间段,需要合理的计算峰值,可能一些并发量不高的系统压根就用不了22台服务器就能支撑,所以需要根据业务去合理计算。还要提前预估我们的业务表,如果3-5年单表规模可能达到500万或者2G的话,需要提前做好分库分表的方案,否则不考虑。


压测


我们设计完系统后,不压测都是对不起小王八这个称号的。我们项目进行到一定阶段,可以配合着jmeter进行项目的压测。压测有许多好处,比如可以提前发现某些问题,如线程安全,并发量等。还能观察到JVM的情况,做好系统调优的准备


JVM调优


压测完后,我们可以根据GC情况对系统做一些性能的调优。不要盲目的认为把堆内存给大一点就高枕无忧了。之前见过一个内部系统,上门来就是Xmx=6G Xms=6G后面就不管了。我想说,你怕是石乐志哦。先不说你们公司有没有钱,内存的价格是非常昂贵的,其次这个6G对于系统造成的影响也是非常巨大的,堆内存越大老年代越大,每次FullGC时间都非常长,你有没有去考察过GC时间,STW对系统造成的影响,每次遇到问题都是重启?那么公司要你来是干什么的呢。所以我们需要JVM调优的一些知识


部署

 

其实开发也是需要了解一些运维知识的,你不知道部署方式,你跟运维吵架都没底气。部署方案我们可以选择docker容器化部署,编排工具有很多docker-compose,meos,k8s等。k8s是一种大趋,所以你可以毫不犹豫的选择k8s部署


总结


其实一套好的架构并不是一开始就搭建好的,而是配合着业务慢慢演变改进的。但是对于我们来说需要的提前掌握的技术就非常多,要不就会埋下许多坑,后期项目无法继续,只有重构。这里我只是简单提了一下系统的设计方案,真正要考虑的远不止于此。假设系统选用springcloud作为微服务的开发框架,那么我们来总结一下需要注意的点

注册中心的选择(eureka,console,nacos,zk)

服务之间的交互ribbon/feign/loadbanlance

服务的熔断,降级措施hystrix/r4j/sentinel

分布式配置中心的选择config/apollo/nacos

网关的选择zuul1.0/2.0/gateway

分布式id生成规则

redis采用哨兵还是集群

redis备份方案rdb/aof

redis缓存淘汰策略/key过期策略

消息中间件(MQ)的选择

日志收集策略(ELK,EFK)

系统的监控,告警

业务知识的储备,代码优化点等等都是需要提前储备的,这里我们知识提出一些自己的观点,真正的使用就要从具体业务场景去分析,这样一套下来,你就对得起小王八这个称号了,你就是最靓的仔。


欢迎各位大佬指正,以上内容都是小白摸索出来。

k8s集群文档/高可用集群文档(ha+keepalive)

springcloud+oauth2.0项目搭建

码云搜索yangyao

欢迎赞赏,不接受批评[旺柴]


文章转载自杨遥,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论