一、需求缘起

明明架构要求高可用, 为何系统中还会存在单点?

回答:单点 master 的设计,会 大大简化系统设计,何况有时候避免不了单点

在哪些场景中会存在单点?先来看一下一个 典型互联网高可用架构 。

典型互联网高可用架构:

( 1 ) 客户端层 ,这一层是浏览器或者 APP ,第一步先访问 DNS-server ,由域名拿到 nginx 的外网 IP

( 2 ) 负载均衡层 , nginx 是整个服务端的入口,负责反向代理与负载均衡工作

( 3 ) 站点层 , web-server 层,典型的是 tomcat 或者 apache

( 4 ) 服务层 , service 层,典型的是 dubbo 或者 thrift 等提供 RPC 调用的后端服务

( 5 ) 数据层 ,包含 cache 和 db ,典型的是主从复制读写分离的 db 架构

在这个互联网架构中,站点层、服务层、数据库的从库都可以通过冗余的方式来保证高可用,但至少

( 1 ) nginx 层是一个潜在的单点

( 2 )数据库 写库 master 也是一个潜在的单点

再举一个 GFS ( Google File System )架构的例子。

GFS 的系统架构里主要有这么几种角色:

( 1 ) client ,就是发起文件读写的调用端

( 2 ) master ,这是一个单点服务,它有全局事业,掌握文件元信息

( 3 ) chunk-server ,实际存储文件额服务器

这个系统里, master 也是一个单点的服务, Map-reduce 系统里也有类似的全局协调的 master 单点角色。

系统架构设计中,像 nginx , db-master , gfs-master 这样的单点服务,会存在什么问题,有什么方案来优化呢,这是本文要讨论的问题。

二、单点架构存在的问题

单点系统一般来说存在 两个很大的问题 :

( 1 ) 非高可用 :既然是单点, master 一旦发生故障,服务就会受到影响

( 2 ) 性能瓶颈 :既然是单点,不具备良好的扩展性,服务性能总有一个上限,这个单点的性能上限往往就是整个系统的性能上限

接下来,就看看有什么优化手段可以优化上面提到的两个问题

三、 shadow-master 解决单点高可用问题

shadow-master 是一种很常见的解决单点高可用问题的技术方案。

“ 影子 master” ,顾名思义,服务正常时,它只是单点 master 的一个影子,在 master 出现故障时, shadow-master 会自动变成 master ,继续提供服务。

shadow-master 它能够解决高可用的问题,并且故障的转移是自动的,不需要人工介入,但不足是它使 服务资源的利用率降为了 50% , 业内经常使用 keepalived+vip的方式实现这类单点的高可用 。

以 GFS 的 master 为例, master 正常时:

( 1 ) client 会连接正常的 master , shadow-master 不对外提供服务

( 2 ) master 与 shadow-master 之间有一种存活探测机制

( 3 ) master 与 shadow-master 有相同的虚 IP ( virtual-IP )

当发现 master 异常时:

shadow-master 会自动顶上成为 master ,虚 IP 机制可以保证 这个过程对调用方是透明的

除了 GFS 与 MapReduce 系统中的主控 master , nginx 亦可用类似的方式保证高可用,数据库的主库 master (主库)亦可用类似的方式来保证高可用,只是细节上有些地方要注意:

传统的一主多从,读写分离的 db 架构,只能保证读库的高可用,是无法保证写库的高可用的,要想保证写库的高可用,也可以使用上述的 shadow-master 机制:

( 1 )两个主库设置 相互同步的双主模式

( 2 )平时只有一个主库提供服务,言下之意, shadow-master 不会往 master 同步数据

( 3 )异常时,虚 IP 漂移到另一个主库, shadow-master 变成主库继续提供服务

需要说明的是,由于数据库的特殊性,数据同步需要时延,如果数据还没有同步完成,流量就切到了 shadow-master ,可能引起小部分数据的不一致。

四、减少与单点的交互,是存在单点的系统优化的核心方向

既然知道单点存在性能上限,单点的性能(例如 GFS 中的 master )有可能成为系统的瓶颈,那么, 减少与单点的交互,便成了存在单点的系统优化的核心方向。

怎么来减少与单点的交互,这里提两种常见的方法。

批量写

批量写是一种常见的提升单点性能的方式。

例如一个利用数据库写单点生成做 “ID 生成器 ” 的例子:

( 1 )业务方需要 ID

( 2 )利用数据库写单点的 auto increament id 来生成和返回 ID

这是一个很常见的例子,很多公司也就是这么生成 ID 的,它利用了数据库写单点的特性,方便快捷,无额外开发成本,是一个非常帅气的方案。

潜在的问题是:生成 ID 的并发上限,取决于单点数据库的写性能上限。

如何提升性能呢?批量写

( 1 )中间加一个服务,每次从数据库拿出 100 个 id

( 2 )业务方需要 ID

( 3 )服务直接返回 100 个 id 中的 1 个, 100 个分配完,再访问数据库

这样一来,每分配 100 个才会写数据库一次,分配 id 的性能可以认为提升了 100倍。

客户端缓存

客户端缓存也是一种降低与单点交互次数,提升系统整体性能的方法。

还是以 GFS 文件系统为例:

( 1 ) GFS 的调用客户端 client 要访问 shenjian.txt ,先查询本地缓存, miss 了

( 2 ) client 访问 master 问说文件在哪里, master 告诉 client 在 chunk3 上

( 3 ) client 把 shenjian.txt 存放在 chunk3 上记录到本地的缓存,然后进行文件的读写操作

( 4 )未来 client 要访问文件,从本地缓存中查找到对应的记录,就不用再请求 master 了,可以直接访问 chunk-server 。如果文件发生了转移, chunk3 返回 client 说“文件不在我这儿了”, client 再访问 master ,询问文件所在的服务器。

根据经验,这类缓存的命中非常非常高,可能在 99.9% 以上(因为文件的自动迁移是小概率事件),这样与 master 的交互次数就降低了 1000 倍。

五、水平扩展是提升单点系统性能的好方案

无论怎么批量写,客户端缓存,单点毕竟是单机,还是有性能上限的。

想方设法水平扩展,消除系统单点,理论上才能够无限的提升系统系统。

以 nginx 为例,如何来进行水平扩展呢?

第一步的 DNS 解析,只能返回一个 nginx 外网 IP 么?答案显然是否定的, “ DNS轮询”技术 支持 DNS-server 返回不同的 nginx 外网 IP ,这样就能实现 nginx 负载均衡层的水平扩展。

DNS-server 部分,一个域名可以配置多个 IP ,每次 DNS 解析请求,轮询返回不同的 IP ,就能实现 nginx 的水平扩展,扩充负载均衡层的整体性能。

数据库单点写库也是同样的道理,在数据量很大的情况下,可以通过水平拆分,来提升写入性能。

遗憾的是, 并不是所有的业务场景都可以水平拆分 ,例如秒杀业务,商品的条数可能不多,数据库的数据量不大,就不能通过水平拆分来提升秒杀系统的整体写性能(总不能一个库 100 条记录吧?)。

六、总结

今天的话题就讨论到这里,内容很多,占用大家宝贵的时间深表内疚,估计大部分都记不住,至少记住这几个点吧:

( 1 ) 单点系统存在的问题 : 可用性问题,性能瓶颈问题

( 2 ) shadow-master 是一种常见的解决单点系统可用性问题的方案

( 3 ) 减少与单点的交互 ,是存在单点的系统优化的核心方向,常见方法有 批量写,客户端缓存

( 4 ) 水平扩展 也是提升单点系统性能的好方案

如果有收获,帮忙随手转发哟。

==【完】==

http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959480&idx=1&sn=337bd74410a6bef616128fd17abd08a8&scene=0&utm_source=tuicool&utm_medium=referral

转载于:https://www.cnblogs.com/CoreXin/articles/5688012.html

单点系统架构的可用性与性能优化相关推荐

  1. 单点系统的高可用与性能优化

    单点系统的问题 1.非高可用:既然是单点,master一旦故障,服务就会收到影响. 2.性能瓶颈:既然是单点,不具备良好的扩展性,单点的服务性能总有个上限,一旦出现单点的上限,往往就是整个系统的上限. ...

  2. C语言嵌入式系统编程修炼之道——性能优化篇

    C语言嵌入式系统编程修炼之道--性能优化篇 作者:宋宝华  e-mail:[email]21cnbao@21cn.com[/email] 1.使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌 ...

  3. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  4. 【Java架构师】JVM性能优化(一)JVM技术入门下

    JVM性能和"一次编译,到处运行"的挑战 我有新的消息告诉那些固执的认为Java平台本质上是缓慢的人.当Java刚刚做为企业级应用的时候,JVM被诟病的Java性能问题已经是十几年 ...

  5. Spark Streaming 实时计算在甜橙金融监控系统中的应用、性能优化、任务监控

    1 写在前面 目前公司对实时性计算的需要及应用越来越多,本文选取了其中之一的 Spark Streaming 来介绍如何实现高吞吐量并具备容错机制的实时流应用.在甜橙金融监控系统项目中,需要对每天亿万 ...

  6. C语言嵌入式系统编程修炼之(六)性能优化

    C语言嵌入式系统编程修炼之性能优化 使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法. 写一个"标准"宏MI ...

  7. 腾讯云低延时直播系统架构设计与弱网优化实践

    "直播带货"可能是2020年最具代表性的词汇之一,那么传统电商该如何融合直播系统,直播过程如何保障用户的最佳观看体验?本文由腾讯云资深架构师何书照在LiveVideoStack线上 ...

  8. mysql性能调优与架构设计 51cto_MySQL 数据库性能优化之表结构优化

    很多人都将 数据库设计范式 作为数据库表结构设计"圣经",认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求.殊不知,在N年前被奉 ...

  9. 开发十年老架构师:Android性能优化实践,程序员如何应对中年危机

    public static Context context; @Override protected void onCreate(Bundle savedInstanceState) { super. ...

最新文章

  1. 在代码中获取ApplicationContext实例
  2. 关于A*寻路算法的认识
  3. 源码编译安装mysql,DDL数据定义语言的使用。
  4. 哈,又一款超级简单的队列(MQ)实现方案来了~
  5. ustc小道消息20211230
  6. C++和Rust_【Rust水群夜话】盘点Rust 官方团队2019年进展
  7. sql 查询 定义变量
  8. Oracle Partition Outer Join 稠化报表
  9. apache 已经加载模块,但是不能解析出开发的rewrite模块功能
  10. dapper使用时性能优化
  11. “吃神么,买神么”的第三个Sprint冲刺总结
  12. 80 after generation to marry or not to marry that is a question
  13. MATLAB中矩阵与数组的区别,点运算符的运用
  14. python运行方法_对python中执行DOS命令的3种方法总结
  15. linux+读取初始化文件,Linux 初始化系统 SystemV Upstart
  16. VS2017报错 class “Cxxxx“没有成员“GetContextMenuManager“ “GetContextMenuManager“:不是“Cxxxx“的成员
  17. C:/Inetpub/AdminsScripts的常用语法
  18. 【Stochastic Depth】《Deep Networks with Stochastic Depth》
  19. 以创新精神,重塑业务流程
  20. AlexNet网络结构详解与代码复现

热门文章

  1. 安装rational rose
  2. 检查本地服务器是否配置成功
  3. 一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」
  4. 一文了解OOM及解决方案
  5. 想过没有,Spring的Bean为啥默认单例?
  6. GOPATH与工作空间
  7. Redis:master/slave、sentinel、Cluster简单总结
  8. STL系列:关联容器的操作
  9. element ui 中el-input搜索输入框或者普通输入框无法输入的问题讨论
  10. Java洛谷P1149 火柴棒等式