分布式系统-->(关于系统应用的基本概念)

分布式系统-->(关于系统应用的基本概念)


最近想了一下,个人学习使用了很多很优秀的开源技术,然后也看了一些的书籍,感觉需要去整理一下,然后分享出来,一方面是一个知识总结,第二方面是有一个知识共享,期间会写一些关于分布式系统的基础知识,包括分布式系统会遇到的问题,然后是各种分布式应用, 会设计到消息队列,搜索引擎,甚至是各种数据库的相关实现内容,然后给自己定一个分享计划是,周期为每周一篇,deadline为每周二(毕竟deadline是第一生产力)

关于系统应用的基本概念


在写其他内容之前,我感觉应该先写一些对于系统的基本知识,然后就是我们在设计或则应用维护一个好的系统需要有哪些好的指标。


可靠性


第一个的话是可靠性,可以简单的理解就是所有的系统都流畅正常的工作,也有一些公司会制定一些指标去固化可靠性,如SLA。每个人在不同的环境下,应该都会有自己的理解,比如说是系统一直正常运行,然后系统可以忍受一部分误操作,系统通过限流等方式正常的拒绝一些不正常的用户请求,也可能是系统能够一定程度的避免一些硬件故障,如有cpu故障,内存条故障,网络中断,磁盘异常等。我们可以试想一下,如果一个分布式存储节点有1000个disk节点,那么故障可能就是是一种常态,因为基数太大,那么造成故障的几率假设是1/1000,那么每天就可能有一个磁盘故障,相信类似这样的事情在大的云数据中心肯定是经常发生,比如aws, google coud。


扫描二维码关注公众号,回复: 4052852 查看本文章

还可能对可靠性有影响的就是软件自身的bug了,肯定的是所有的软件都会有bugs,甚至强如linux内核, mysql这样的被严格验证的系统都会有bugs, 所以这是不能被避免的,只能说我们去减少这样的bugs异常,优化流程,减少类似异常的发生,如用完善的监控和告警,完整的工作流测试,严格的系统进程隔离,允许进行异常检测和重启等一些流程增强系统可靠性。


最后的话可能是人为的处理异常,系统都需要人去维护,需要人去控制系统的正常运行,即便是像kubernetes优秀的工具也需要人维护。可以这么说,即便是最优秀的工程师去维护的也一定会出错,而且权限约大越可能会有故障。我们只能尽可能的去减少。比如减少出现异常的概率,如设计的时候提供标准的rest api控制, admin dashboard控制界面权限,最少也要有完善的文档,这块是非常有用的,比如像rabbitmq 提供了admin 页面去控制整个集群,包括用户权限控制,队列控制,vhost隔离,这都简化用户操作,一定程度上减少认为操作导致的系统异常。

然后的话可以进行定期的进行一个演练,这个演练可以是一种系统故障模拟,测试系统是否符合预期工作,也可以让我们更熟悉我们的操作,在一个就是提供一些能够简化回滚的配置文件,或则是更容易操作的回滚工具,比如像oracle 就会数据库回闪,如果有异常操作也能进行一个数据库回闪。


在这一块,现在能看到越来越多的软件在设计的时候在考虑了可靠性,就是大家都将"服务只要运行就一定有异常的情况"当做了一种共识,所有设计的时候就考虑了分布式的情况,提高容错率,增强可靠性,像hdfs, zookeeper, kafka, es, mongdb 等等,都有各自的机制去保证可用性,最常见的就是master-salve, 也有叫primary-secondary。

可扩展性

这几乎是所有系统都会遇到的问题,想象一下,当你网站的用户随着时间的增长越来越多,需要的流量和数据的存储等各项资源都在增长,那么你怎么去保证你系统还能一直正常工作,还保证正常的负载和响应延时。

这个问题可以很简单的问自己,如果用户系统增加了2倍,系统能否正常运行?

要问答这个问题,需要清楚的知道当前系统的负载和当前系统的性能瓶颈在哪。负载的话可以被定义为为,游戏里边的话就是在线人数,web相关的服务qps, 数据库的tps, 缓存的命中率等,机器资源的cpu/mem的使用率等。

还有一个数据就是性能,简单理解就是在你负载增长的情况下,在保持系统资源都不变的情况下(如cpu/mem/io等等),对系统最大的影响是什么。然后当你增加了一些负载,你需要怎么增加资源才能保证性能不变。比如说消息队列会有一些吞吐量(throughtout)的概念,即为一分钟能够处理的消息量是多少,又比如说响应时间(respone-time),就是能正常响应服务的时间,还比如gc垃圾回收的效率,堆栈的使用效率等等,你怎么去保证他们保持原来的状态。

整个的话就是想说我们的系统设计不可能一直是不变的,一直都会是变化的的,然后我们需要设计我们的系统在保证性能的同时具有可扩展性,满足我们的扩展需求,比如就对存储来说,目的是就是简单的增加磁盘,增加主机,增加资源就可达到我们的目的,开源数据库里边已经有很多在软件设计就考虑到了这些问题,如果像mongdb,es,他们是一种可扩展的数据库,他们有sharding,就是将数据分散到不同的计算节点上,然后有相关进程进行路由转发和结果汇聚,还有像kafka消息队列,也有数据分区,不同topic进行Partition, 将不同数据分散,然后满足扩展性。像mysql虽然官方没有提供很好的扩展方案(NDK在国内用的比较少),不过社区也做了很多基于mysql的扩展,像读写分离中间件,分库分表中间件,maxscale, mycat, sharding-sphere等等工具。所以可扩展性是应用程序设计也是必不可少的。


可维护性

然后最后的话就是可维护性,这块大家都很容易被忽视,觉得只要能用就行,其实不是这样,这块对我们服务也是非常重要的。因为自己也在研究很多的应用服务软件,然后也应用了很多在公司中,对我来说,可维护性是非常重要的指标,因为这会和我的工作直接相关,想象一下,如果说我去使用一个没有文档,没有测试报告,没有管理工具的软件,这会是多么懊恼的一件事,你要去处理所有的坑,然后出了问题也没有很好地方式去解决,维护可能带来很大的成本,也很容易进行误操作,对时间的把控,和软件的把控都不能游刃有余,那对系统来说就是一个很大潜在的威胁。


所有说如果你是一个研发,当你设计的软件需要进行交付的时候,你应该去多想想,是否设计的软件方便维护,比如是否有完善的文档,完善的部署脚本,回滚脚本,升级工具,系统状态监控,服务扩容,缩容的步骤等。这样做下来会减少你排查问题,修复问题的时间,也会提高服务的SLA。


这里的话,推荐一个最佳比较火的容器编排工具, kubernetes, 它和ansible ,salt-statck思路不一样,它不仅仅是一个批量控制,管理主机的工具,它还能管理你的服务,监控,甚至是修复你的服务,当服务以docker的方式的时候,理想状态是以后你就不需要去维护了,而且更赞的是如果你设计的软件能能水平扩展,那么就更好了,它能用hpa的方式,自动的进行扩容缩容,结合云计算平台的话,甚至能弹性的扩展底层的计算存储网络相关资源。我是较早一批吃螃蟹的人,感觉非常不错。


简单整理


以上几个指标我觉得是软件设计中的一些基本概念,我们设计的服务软件应该尽可能的满足上边的目标,对系统而言会更有帮助。同时这些也是分布式系统设计一些基本概念,有了概念这些我们才能从更好的角度去看其他优秀的分布式系统的设计思路和方法。


猜你喜欢

转载自juejin.im/post/5be9a01ff265da616b103d9e
今日推荐