单点系统架构的可用性与性能优化
一、需求缘起
明明架构要求高可用, 为何系统中还会存在单点?
回答:单点 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.非高可用:既然是单点,master一旦故障,服务就会收到影响. 2.性能瓶颈:既然是单点,不具备良好的扩展性,单点的服务性能总有个上限,一旦出现单点的上限,往往就是整个系统的上限. ...
- C语言嵌入式系统编程修炼之道——性能优化篇
C语言嵌入式系统编程修炼之道--性能优化篇 作者:宋宝华 e-mail:[email]21cnbao@21cn.com[/email] 1.使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌 ...
- Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析
Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...
- 【Java架构师】JVM性能优化(一)JVM技术入门下
JVM性能和"一次编译,到处运行"的挑战 我有新的消息告诉那些固执的认为Java平台本质上是缓慢的人.当Java刚刚做为企业级应用的时候,JVM被诟病的Java性能问题已经是十几年 ...
- Spark Streaming 实时计算在甜橙金融监控系统中的应用、性能优化、任务监控
1 写在前面 目前公司对实时性计算的需要及应用越来越多,本文选取了其中之一的 Spark Streaming 来介绍如何实现高吞吐量并具备容错机制的实时流应用.在甜橙金融监控系统项目中,需要对每天亿万 ...
- C语言嵌入式系统编程修炼之(六)性能优化
C语言嵌入式系统编程修炼之性能优化 使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法. 写一个"标准"宏MI ...
- 腾讯云低延时直播系统架构设计与弱网优化实践
"直播带货"可能是2020年最具代表性的词汇之一,那么传统电商该如何融合直播系统,直播过程如何保障用户的最佳观看体验?本文由腾讯云资深架构师何书照在LiveVideoStack线上 ...
- mysql性能调优与架构设计 51cto_MySQL 数据库性能优化之表结构优化
很多人都将 数据库设计范式 作为数据库表结构设计"圣经",认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求.殊不知,在N年前被奉 ...
- 开发十年老架构师:Android性能优化实践,程序员如何应对中年危机
public static Context context; @Override protected void onCreate(Bundle savedInstanceState) { super. ...
最新文章
- 在代码中获取ApplicationContext实例
- 关于A*寻路算法的认识
- 源码编译安装mysql,DDL数据定义语言的使用。
- 哈,又一款超级简单的队列(MQ)实现方案来了~
- ustc小道消息20211230
- C++和Rust_【Rust水群夜话】盘点Rust 官方团队2019年进展
- sql 查询 定义变量
- Oracle Partition Outer Join 稠化报表
- apache 已经加载模块,但是不能解析出开发的rewrite模块功能
- dapper使用时性能优化
- “吃神么,买神么”的第三个Sprint冲刺总结
- 80 after generation to marry or not to marry that is a question
- MATLAB中矩阵与数组的区别,点运算符的运用
- python运行方法_对python中执行DOS命令的3种方法总结
- linux+读取初始化文件,Linux 初始化系统 SystemV Upstart
- VS2017报错 class “Cxxxx“没有成员“GetContextMenuManager“ “GetContextMenuManager“:不是“Cxxxx“的成员
- C:/Inetpub/AdminsScripts的常用语法
- 【Stochastic Depth】《Deep Networks with Stochastic Depth》
- 以创新精神,重塑业务流程
- AlexNet网络结构详解与代码复现