阅读更多
引言

在分布式系统中,经常会碰到的技术名词一般有Replication、Partition、Consensus、Transaction等等,这些技术在分布式系统设计中都是非常重要的,本文通过对分布式系统的Reliability、Scalability和Maintainability特性的讨论,描述这些技术解决的问题。

Reliability

Reliability,指的是在任何情况下,系统正常工作的能力。如果一个系统在发生任何异常时,都能正常的工作,那么系统是完全可靠的。现实中,异常种类很多,有的往往难以事先避免,因此,了解可能的异常并分析如何在异常发生时快速恢复是非常重要的。一般地,异常包括硬件异常,软件异常和人为异常。

硬件异常

硬件异常种类很多,硬盘,电源等任意一个部件的损坏,都可能导致服务器不能正常的工作。通常这类异常难以避免,但是,我们可以通过一些技术手段来实现异常发生后的快速恢复,不管是从软件角度还是硬件角度,基本的解决思路都是冗余。从硬件角度来讲,我们可以通过单机冗余多份硬件,当其中某个硬件发生异常时,可以快速地用好的硬件替换掉故障的硬件,这种方式的硬件冗余对于数据中心级的故障是没有作用的;从软件角度来讲,我们可以通过多副本(Replication)来实现快速恢复,当某台服务器硬件异常时,可以在软件层面将流量导入到新的副本上(实际上也有硬件冗余,但这种方式更为灵活),除了Replication之外,有时候为了减少单台服务器故障对所有用户的影响,可以对用户数据做Partition,单台服务器只存某一部分用户的数据,这样单机故障就只会影响一部分用户了。引入Replication后,如何保证多副本的数据的一致性又成了一个问题(Consensus),Paxos和Raft算法就是为了解决这类问题。

软件异常

软件异常一般指的是系统的bug,这里面不仅包括自己写的系统的bug,也包括依赖的服务系统的bug。软件异常同样也是不能完全避免的,因此,在发生软件异常时,也需要有快速恢复的手段,通常有三种方法:
  • 通过调整软件已有的配置参数,规避问题
  • 重启软件或者依赖的服务,消除异常状态
  • 直接修复bug,并升级版本
在没有发生致命性问题时,一般采用方法1或2来恢复,当发生的问题比较严重,并且没有已知的方法能绕过时,一般才使用方法3,方法3本身风险也是比较大的,因为修复bug的同时可能会产生新的bug。

人为异常

不管是软件本身,还是软件所运行的服务器,都是由人来管理的,但人是会犯错误的,有时候会执行错误的命令导致系统不能正常工作,其中比较致命的错误可能就是删掉某台服务器的数据了,在这种情况下为了能快速地恢复,通常也是采用Replication的思路,来避免问题。

Scalability

系统的工作负载通常不是一成不变的,当工作负载增加时,往往可以通过增加机器资源来保持性能不变,而需要增加机器数量的多少是由系统的扩展性来决定的,扩展性越好的系统,需要增加的机器资源越少。最完美的扩展性是线性扩展性,即工作负载扩大为原来N倍的时候,只需要加N倍的机器,就能够保持性能不变,最差的扩展性则是没有扩展性,即工作负载扩大为原来N倍时,即使加再多的机器,也无法保持性能和原来一样。

对于不同的系统,负载所代表的含义通常是不一样的,对于基础架构系统,通常每秒读和每秒写的次数,对于业务系统,通常有自己的指标,例如每秒交易创建的笔数。同样地,对于不同的系统,其使用的性能指标通常也是不相同的,对于批处理系统,通常强调的是吞吐量,即每秒完成的任务数量,而对于在线处理系统,通常强调的是响应时间。

在明确一个系统的工作负载指标和性能指标之后,我们才能讨论在该系统下如何实现扩展。扩展通常是两种思路,一是垂直扩展,即使用更好的机器替换现有的机器,二是水平扩展,即使用更多的机器。

对于垂直扩展,其优点是对业务是无影响的,缺点是更好的机器是很贵的,通常是一分钱一分货,而十分钱只能买到两分货,且现实中总有单机装不下的数据量,此时垂直扩展自然就无法实施了。

对于水平扩展,通常需要软件层面的配合,对于无状态的系统,通常只要在新加的机器上部署上需要扩展的系统,而对于有状态的系统,一般指的是存储系统,通常会将数据分成Partition(分区),这样新加的机器才能通过迁移Partition的方式,从老的机器上迁移数据以及对应的工作负载出来。水平扩展的优点是使用的都是相对廉价的服务器,能节约成本,但在软件层面需要做大量的工作,包括Partition的管理,迁移,负载均衡等等。

Maintainability

可维护性的好坏决定了系统是否能够长久的发展,一个可维护性不好的系统,会给运维和开发人员带来很多不便。对于运维人员来讲,可维护性指的是系统是否支持常用的运维手段,良好的文档等等。而对于开发人员来讲,主要分为内核开发以及使用该系统的业务开发,对于业务开发,维护性指的是系统是否有良好的接口,方便业务使用,例如,Transaction就是底层系统提供给业务的一种接口,它保证了在一个事务中执行的语句具有ACID性质,从而业务只需要关注业务逻辑的开发,而不需要关心底层的具体实现;对于内核开发,维护性指的是系统的代码质量,主要包括代码的可阅读性和是否易于修改,主要和系统内核开发人员的代码设计能力相关。

总结

为了能达到较好的可靠性(Reliability)、可扩展性(Scalability)和可维护性(Maintainability),分布式系统设计中通常会使用多副本(Replication)、数据分区(Partition)、一致性算法(Consensus)、事务(Transaction)等技术,理解它们要解决的问题,深入了解每种技术背后可能的实现方案,有助于评价某个系统的设计好坏,这对于多个竞品系统的选型和深入学习系统原理都是非常有必要的。
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • MFC 内嵌对话框增加滚动条实现页面响应鼠标滚动

    最近新开发的项目中,页面控件太多,子对话框的长度明显大于主对话框,嵌入到主对话框后,会覆盖主对话框页面,需要实现子对话框页面的滚动,网上查了很多方法,大多需要拖动滑块,实现滚动,没有响应鼠标滚动的,在此记录一下,参考博客

  • 关于ListCtrol的owner-draw和custom-draw

    一、所有者绘制(owner-draw)和自定义绘制(custom-draw) 一、给控件添加排序功能report风格的list控件很多情况下都需要支持排序功能,而且最好支持按不同列进行排序。CListCtrl的类方法SortItems支持排序功能,但是在排序过程中,两个数据真正的比较过程是通过SortItems的第一个参数指向的回调比较函数来完成的。这个函数通过比较SetItemDat...

  • 2012-11-26

    10:08 1.鼠标滚轮控制文本滚动条    需要响应OnMouseWheel。重载这个函数,只需要声明afx_msg BOOL OnMouseWheel(UINT fFlags, short zDelta, CPoint point);不需要去绑定。这个同OnVScroll,OnMouseMove,OnLButtonDown有一样的特点,只需重载声明就OK了。    默认情况下OnMous

  • 急求答案:我在文件转换程序里添加了一个进度条,当点击运行程序后,进度条就先跑,但是我还没有进行文件转换操作那,怎么实现它们的同步??

    进度条的代码如下: BOOL CTestDlg::OnInitDialog()  { CDialog::OnInitDialog();         m_Progress.SetRange32(0,100);     m_Progress.SetStep(5); m_Progress.SetPos(0);     SetTimer(1,500,0); Upd

  • 深入浅出MFC文档/视图架构之视图

    视图类CView  在MFC"文档/视图"架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口。在"文档/视图"架构中,文档负责管理和维护数据;而视图类则负责如下工作:  (1) 从文档类中将文档中的数据取出后显示给用户;  (2) 接受用户对文档中数据的编辑和修改;  (3) 将修改的结果反馈给文档类,由文档类将修改后的内容保存到磁盘文件中。  文档负责了数据真正在永久介质

  • 深入浅出MFC“文档/视图”架构(4)――视图

    深入浅出MFC“文档/视图”架构(4)――视图作者:宋宝华  e-mail:[email]21cnbao@21cn.com[/email]1.视图类CView在MFC“文档/视图”架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口。在“文档/视图”架构中,文档负责管理和维护数据;而视图类则负责如下工作:(1)       从文档类中将文档中的数据取出后显示给用户;(2)  ...

  • MFC对话框Border类型(None、Thin、Resizing、Dialog Frame)对应的部分属性

    在运行中转换对话框类型需要用到的属性 Dialog Frame WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | DS_MODALFRAME WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE Thin 比Dialog Frame缺少一个扩展属性WS_EX_DLGMODALFRAME None 比D...

  • 关于派生MFC通用控件的方法

    <br />由于在MFC中,所有的控件类都是从CWnd类派生而来,所以在派生新的控件类时需要参考CWnd的定义,以此来扩展自己需要的功能。<br /> <br />1. CWnd定义<br />class CWnd : public CCmdTarget { DECLARE_DYNCREATE(CWnd) protected: static const MSG* PASCAL GetCurrentMessage(); // Attributes public: HWND m_hWnd

  • 如何使用滚动条?

    我整理了一下,大家一看就明白怎么回事。滚动条实际很简单,给那些没功夫自己查找的人提供方便,也算是有点贡献。从下面可知,可以分解为3部分。声明和创建滚动条对象设置滚动条大小和位置设置滚动条滑块的位置,更具滑块位置设置其他对象状态// TestdvView.h : interface of the CTestdvView class///////////////////////////////

  • [原创]滚动条滚动范围的问题总结

    [原创]滚动条滚动范围的问题总结 最近在滚动条的问题上纠结了很久,所有问题都归结于一个滚动事件处理函数的bug,就是OnHScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll) 问题是这样出现的:我写了一个显示位图的程序,由于图片长度很长,因此需要滚动条来滚动图片,因此我加了一个滚动条控件,并将它的滚动范围SCROLLINFO.nMax设...

  • ChartCtrl源码剖析之——CChartScrollBar类

    CChartScrollBar类用来针对每个轴的数据进行滚动,将那些不在当前区域内的数据通过滚动展示出来。 CChartScrollBar类的头文件。 #pragma once class CChartAxis; class CChartScrollBar : public CScrollBar { public: CChartScrollBar(CChartA...

Global site tag (gtag.js) - Google Analytics