• Tair的桶分布策略介绍及新的机器级位置安全优先策略实现


    Tair的桶分布策略介绍及新的机器级位置安全优先策略实现

    Tair在其intro wiki 上介绍了其现有的桶分布策略:

      程序提供了两种生成分配表的策略, 一种叫做负载均衡优先, 一种叫做位置安全优先。

      负载均衡优先

      当采用负载优先策略的时候, config server会尽量的把桶均匀的分布到各个data server上. 所谓尽量是指在不违背下面的原则的条件下尽量负载均衡. 1 每个桶必须有COPY_COUNT份数据 2 一个桶的各份数据不能在同一台主机上;

      位置安全优先

      位置安全优先原则是说, 在不违背上面两个原则的条件下, 还要满足位置安全条件, 然后再考虑负载均衡. 位置信息的获取是通过 _pos_mask(参见安装部署文档中关于配置项的解释) 计算得到. 一般我们通过控制 _pos_mask 来使得不同的机房具有不同的位置信息. 那么在位置安全优先的时候, 必须被满足的条件要增加一条, 一个桶的各份数据不能都位于相同的一个位置(不在同一个机房).

      wiki上还针对位置安全优先策略进行了进一步的补充:

      “这里有一个问题, 假如只有两个机房, 机房1中有100台data server, 机房2中只有1台data server. 这个时候, 机房2中data server的压力必然会非常大. 于是这里产生了一个控制参数 _build_diff_ratio(参见安装部署文档). 当机房差异比率大于这个配置值时, config server也不再build新表. 机房差异比率是如何计出来的呢? 首先找到机器最多的机房, 不妨设使RA, data server数量是SA. 那么其余的data server的数量记做SB. 则机房差异比率=|SA – SB|/SA. 因为一般我们线上系统配置的COPY_COUNT是3. 在这个情况下, 不妨设只有两个机房RA和RB, 那么两个机房什么样的data server数量是均衡的范围呢? 当差异比率小于 0.5的时候是可以做到各台data server负载都完全均衡的.这里有一点要注意, 假设RA机房有机器6台,RB有机器3台. 那么差异比率 = 6 – 3 / 6 = 0.5. 这个时候如果进行扩容, 在机房A增加一台data server, 扩容后的差异比率 = 7 – 3 / 7 = 0.57. 也就是说, 只在机器数多的机房增加data server会扩大差异比率. 如果我们的_build_diff_ratio配置值是0.5. 那么进行这种扩容后, config server会拒绝再继续build新表.”

      我们在生产环境中使用时,起初使用的是负载均衡优先,对应的配置文件group.conf中的_build_stategy=1。但是在线上环境中,为了充分利用磁盘IO,经常会在同一台服务器上跑多个dataserver(一个磁盘对应一个dataserver),而通过cst_monitor查看桶分布表,发现wiki中提到的必须遵守的原则“2 一个桶的各份数据不能在同一台主机上”并没有得到满足,只是保证了同一个桶的各份数据不落在同一个dataserver上。这样有一个很严重的问题,如果某台服务器宕机了,就非常有可能导致一个桶的主备bucket都无法对外服务,导致config server拒绝build新的桶分布表(内存级的可能就丢数据了,磁盘级的会造成落在该台服务器上的所有的桶都会写失败)。

         

          这是个很严重的问题,我们首先想到的是复用默认的“位置安全优先策略”,将group.conf中的_pos_mask设成4294967295(0xFFFFFFFF),这样每一台机器都会被认为是不同的位置。但是在使用中发现,程序并没有按照我们预想的那样在多个机器之间分散主备bucket,而是拒绝建表。查看了建表策略的代码table_builder2.cpp发现这个策略只适合于两个位置,即适用于集群在两个机房间的负载均衡,并不适合更多位置(>=3)的位置安全,我们简单的针对机器ip做mask是无效的。

         

          接下来,我们考虑自己实现一个新的位置安全策略,但仔细看了负载均衡优先策略的代码table_builder1.cpp 后,发现可以通过修改table_builder1的代码,实现我们想要的机器级位置安全策略。

          默认的负载均衡优先策略代码,在不同的consider级别下考虑了如下条件(is_this_node_ok()):

          1.主bucket在各实例上分布均匀;

          2.当前主备bucket在实例上分布均匀;

          3.在建表主备bucket在备实例上分布均匀;

          4.主备不在同一个实例上;

          5.主备不在同一个position上(port:ip&mask);

          负载均衡优先策略共有四个consider级别(CONSIDER_ALL\CONSIDER_POS\CONSIDER_BASE\CONSIDER_FORCE),以此考虑4个级别,满足的条件逐渐放松,直到可以成功建表。四个不同的CONSIDER级别分别满足的条件如下:

          CONSIDER_ALL: 1, 2, 4, 5

          CONSIDER_POS: 1, 3, 4, 5

          CONSIDER_BASE: 1, 3, 4

          CONSIDER_FORCE: 1, 4

          可见,默认的策略优先满足的是3(均衡),而非5(postion安全)。这样问题就很简单了,只需要把CONSIDER_BASE满足的条件由1、3、4改成1、4、5,就可以实现我们需要的机器级的位置安全优先策略,同时兼顾机器级别的负载均衡(需要自行保证不同机器的dataserver数尽量均衡,同时group.conf的_pos_mask设成4294967295)。

          给出如下patch:

    复制代码
    @@ -50,7 +50,7 @@
             }
           }
           else {
    -        if(option_level != CONSIDER_FORCE &&
    +        if(option_level < CONSIDER_BASE &&
                tokens_count_in_node_now[node_id] >= tokens_per_node_min + turn &&
                max_count_now >= tokens_per_node_max_count + turn) {
               return TOOMANY_BUCKET;
    @@ -64,7 +64,7 @@
               if(hash_table_dest[i][node_idx].first == node_id.first) {
                 return SAME_NODE;
               }
    -          if(option_level < CONSIDER_BASE) {
    +          if(option_level <= CONSIDER_BASE) {
                 if(hash_table_dest[i][node_idx].second == node_id.second) {
                   return SAME_POS;
                 }
    复制代码

          非常简单的修改。(我们是额外添加了一个新的table_builder3.cpp来作为这个策略的实现,因此还需要对group_info.cpp做修改,生成新策略的p_table_builder,大家可以自行修改)。

    那些年,我们一起追寻的异步编程[系列]

    =============C#.Net 篇目录==============

        哈哈,经过一番努力,我写的异步编程系列也算有头有尾,当然不是说这个系列已经更新完毕,这个头尾只是表示新旧知识点都有简单涉及到,接下去我还会丰富这一系列并且有机会整个小应用(愿景是弄一个开源组件吧,结合socket)。想获取本系列更新的第一手资源,请“加我的关注”……感谢大家一直给予的支持……(*^_^*)……

     

    术语:

    APM             异步编程模型,Asynchronous Programming Model

    EAP               基于事件的异步编程模式,Event-based Asynchronous Pattern

    TAP               基于任务的异步编程模式,Task-based Asynchronous Pattern

    TPL               任务并行库,Task Parallel Library

     

        现在我给这个系列整个目录和做个简单介绍。

    “概要 + 目录”整理

        C#语言是微软于2000年发布,基于.NET Framewrok框架的、面向对象的高级语言。经过近十三年的发展,经历了5次大的升级,目前最新版本为C#5.0(对应于.NET Framework 4.5)。其中每个版本发布都是有一个“主题”。即:C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语言→C#5.0异步编程。这系列既是针对“异步编程”所写。

    C#版本

    .NET 版本

    Visual Studio 版本

    特性描述

    C# 1.0

    .NET 1.0/1.1

    VS 2002/2003

    C#的第一个正式发行版本。微软的团队从无到有创造了一种语言,专门为.NET编程提供支持

     

     

     

    C# 2.0

    .NET 2.0

     

     

     

    VS 2005

    C#语言开始支持泛型,.NET Framework 2.0新增了支持泛型的库

    .NET 3.0

    新增了一套API来支持分布式通信(Windows Communication Foundation— WCF)、富客户端表示(Windows Presentation Foundation)、工作流(Windows Workflow—WF)以及Web身份验证(Cardspaces)

    C# 3.0

    .NET 3.5

    VS 2008

    添加了对LINQ的支持,对用于集合编程的API进行了大幅改进。.NET Framework 3.5对原有的API进行了扩展,从而支持了LINQ   

    C# 4.0

    .NET 4.0

    VS 2010

    添加了动态类型(dynamic)的支持,引入了新的轻量级线程同步基元及新的异步编程类库TPL

    C# 5.0

    .NET 4.5

    VS 2012

    改进并扩展了.NET4.0中引入的TPL类库,并引入async和await关键字轻松构建异步方法。

     

    1. 我的异步编程整理

    资料整理路线:线程----线程池----线程同步----并行任务----三种异步编程模型。首先了解最基础的线程(Thread类),再进一步明白线程管理器(ThreadPool类)。因为多个工作项之间可能出现并行运行,会造成对共享资源的访问问题,所以引入线程同步基元来让共享资源得到合理使用。最后介绍.NET4.0新引入并在.NET4.5中得到优化和扩展的TPL(任务并行库),并结合C# 5.0中新引入的async和await关键字轻松构建异步方法。详细如下:

    异步编程:线程概述及使用

    异步编程:使用线程池管理线程

    异步编程:线程同步基元对象

    异步编程:轻量级线程同步基元对象

    异步编程:.NET4.5 数据并行

    异步编程:异步编程模型 (APM)

    异步编程:基于事件的异步编程模式(EMP)

    异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

     

    1. 我的异步编程外文翻译

    对的,老外的文章总会为我们带来意外的知识和惊喜,往往一些复杂、内核、深入、独到的见解会出现在老外的文章中,此时对于像和我一样E文不好的童鞋就会错过不少经典见解,此处我分享一些在学习异步编程过程中碰到的好E文:

    (译)关于async与await的FAQ

             这篇文章为我带来的不仅仅是async和await关键字的认识,更为我提供了很多关于TPL的扩展资源,我很推荐大家看看这篇博文,当然其中还有不少E文,有时间我会将我认为不错的进行翻译分享。

    像下面所翻译的文章:

    (译).NET4.X 并行任务中Task.Start()的FAQ

    (译).NET4.X并行任务Task需要释放吗?

     

    为TPL提供同步基元,但这只是提供TPL的应用思路,不推荐将这些同步基元应用于项目中。

    (译)构建Async同步基元,Part 1 AsyncManualResetEvent

    (译)构建Async同步基元,Part 2 AsyncAutoResetEvent

    (译)构建Async同步基元,Part 3 AsyncCountdownEvent

    (译)构建Async同步基元,Part 4 AsyncBarrier

    (译)构建Async同步基元,Part 5 AsyncSemaphore

    (译)构建Async同步基元,Part 6 AsyncLock

    (译)构建Async同步基元,Part 7 AsyncReaderWriterLock

     

    1. 待续…异步编程系列持续更新中

    …………

    ……

     

        分享这系列博文过程中一直都感受到大家给予的支持与鼓励让我着实激动不已也让我坚持做下去(杜绝太监作品),现在本系列已有小成,所以将目录整理下方便大家查阅。

    做为知识整理我打着增强自己技术的如意算盘,做为知识分享我希望我的博文能给大家带来更多的知识与惊喜……各位周末加班快乐,51就在眼前……

    喜欢本系列博文的园友还请多多推荐(*^_^*)……感谢大家支持!

     


    作者:滴答的雨 
    出处:http://www.cnblogs.com/heyuquan/ 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

    欢迎园友讨论下自己的见解,及推荐更好资料。 
    本文如对读者有帮助,还请多帮 下此文。 
    谢谢!!!  ( 

     
    分类: C#.Net 篇
    标签: 异步编程
  • 相关阅读:
    软件版本具体代表什么意思
    面向接口的编程
    MySQL mysqldump用法
    常见问答解答
    Perl 语言笔记
    JAVA 基础知识
    面向接口编程的基本原则
    判断文件存在与否【Linux】
    Gtk Label设置字体颜色
    解压缩路径设置【Linux】
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3045983.html
Copyright © 2020-2023  润新知