精华内容
下载资源
问答
  • 我公司前段时间做了一个活动,花了5000块购买了5台虚拟机(每台cpu 为单核2GHZ,内存为1.5GB)做了一个两个月大活动,我设计支持并发系统如下: 活动特点是并发,逻辑不是很复杂,因此我采用DNS做负载均衡器+...

    我公司前段时间做了一个活动,花了5000块购买了5台虚拟机(每台cpu 为单核2GHZ,内存为1.5GB)做了一个两个月大活动,我设计支持高并发的系统如下:
    活动的特点是高并发,逻辑不是很复杂,因此我采用DNS做负载均衡器+nginx做前端+php开发+redis数据库的分布式结构。
    使用DNS负载均衡的原因是,我没有更多的钱买负载均衡,其次负载均衡至少得双机主备,再次DNS负载均衡不用部署配置,比lvs简单多了。
    为了解决跨域的session问题,我使用了一个redis数据库来存储session的id,这样我的php程序得改成不读取本地session,而去读取redis中的session数据。可以实现跨域的session,不用担心分布式带来的session问题。
    同时redis可以用作存储用户数据,例如微博id,生成图片路径等等信息,并发性要比mysql高得多。
    为了解决redis单点故障,我添加了一个从redis数据库实时和主redis数据库进行同步,若是主数据库挂了,可以用从数据库来顶替

     

     

     

    但是这个网站每台机器上都会生成各自的图片,而这些图片需要在网站上显示,这样的话存在一个问题:
    某个用户是通过DNS只能请求到一台机器上(VM3)上,那么在网站上出现的VM2,VM4,VM5的图片就无法显示了。
    我冥思苦想,想到了一个好办法:就是利用nginx的proxy模块来实现:
    1)VM2上由程序生成的每一张的图片都存在目录(10.200.225.158--VM2的内网ip)下,VM3上由程序生成的每一张的图片都存在目录(10.200.226.56)下...
    2) 这样VM2下的图片路径就是http://www.a.com/10.200.225.158/xxx.jpg,VM3下的图片就是http://www.a.com/10.200.226.56/xxx.jpg
    3)我VM2上的nginx上配置使得:
        3.1)当用户被DNS解析到VM2上时,若URL是http://www.a.com/10.200.225.158/xxx.jpg时就直接读取本地图片
        3.2)当用户被DNS解析到VM2上时,若URL是http://www.a.com/10.200.226.56/xxx.jpg时就通过VM2代理读取远程的VM3上的图片
        3.3)当用户被DNS解析到VM2上时,若URL是http://www.a.com/10.200.55.39/xxx.jpg时就通过VM2代理读取远程的VM4上的图片
        3.4)当用户被DNS解析到VM2上时,若URL是http://www.a.com/110.200.51.143/xxx.jpg时就通过VM2代理读取远程的VM5上的图

     

     

     

     

    也就是说当www.a.com解析到vm2,若是要显示vm3上生成的图片的话,得通过vm2的代理去获取,由于我设置的代理的ip都是内网的,因此不占用外网ip的网络资源,不影响用户的访问速度。  


    vm2的nginx配置文件如下

     

    
    
    1. location /10.200.226.56 {  
    2.              root    /opt/tmp/;  
    3.              proxy_redirect off ;  
    4.              proxy_set_header Host $host;  
    5.              proxy_set_header X-Real-IP $remote_addr;  
    6.              proxy_set_header REMOTE-HOST $remote_addr;  
    7.              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
    8.              client_max_body_size 50m;  
    9.              client_body_buffer_size 256k;  
    10.              proxy_connect_timeout 30;  
    11.              proxy_send_timeout 30;  
    12.              proxy_read_timeout 60;  
    13.              proxy_buffer_size 256k;  
    14.              proxy_buffers 4 256k;  
    15.              proxy_busy_buffers_size 256k;  
    16.              proxy_temp_file_write_size 256k;  
    17.              proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;  
    18.              proxy_max_temp_file_size 128m;  
    19.              proxy_pass    http://10.200.226.56:80;  
    20.                
    21. }  
    22.  
    23. location /10.200.55.39 {  
    24.              root    /opt/tmp/;  
    25.              proxy_redirect off ;  
    26.              proxy_set_header Host $host;  
    27.              proxy_set_header X-Real-IP $remote_addr;  
    28.              proxy_set_header REMOTE-HOST $remote_addr;  
    29.              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
    30.              client_max_body_size 50m;  
    31.              client_body_buffer_size 256k;  
    32.              proxy_connect_timeout 30;  
    33.              proxy_send_timeout 30;  
    34.              proxy_read_timeout 60;  
    35.              proxy_buffer_size 256k;  
    36.              proxy_buffers 4 256k;  
    37.              proxy_busy_buffers_size 256k;  
    38.              proxy_temp_file_write_size 256k;  
    39.              proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;  
    40.              proxy_max_temp_file_size 128m;  
    41.              proxy_pass    http://10.200.55.39:80;  
    42.                
    43. }  
    44. location /10.200.51.143 {  
    45.              root    /opt/tmp/;  
    46.              proxy_redirect off ;  
    47.              proxy_set_header Host $host;  
    48.              proxy_set_header X-Real-IP $remote_addr;  
    49.              proxy_set_header REMOTE-HOST $remote_addr;  
    50.              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
    51.              client_max_body_size 50m;  
    52.              client_body_buffer_size 256k;  
    53.              proxy_connect_timeout 30;  
    54.              proxy_send_timeout 30;  
    55.              proxy_read_timeout 60;  
    56.              proxy_buffer_size 256k;  
    57.              proxy_buffers 4 256k;  
    58.              proxy_busy_buffers_size 256k;  
    59.              proxy_temp_file_write_size 256k;  
    60.              proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;  
    61.              proxy_max_temp_file_size 128m;  
    62.              proxy_pass    http://10.200.51.143:80;  
    63.                
    64. }  
    65.  
    66. location ~ \.php$ {  
    67.            fastcgi_pass   127.0.0.1:9000;  
    68.            fastcgi_index  index.php;  
    69.            fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;  
    70.            include        fastcgi_params;  

     





         本文转自yifangyou 51CTO博客,原文链接:http://blog.51cto.com/yifangyou/1047427,如需转载请自行联系原作者


    展开全文
  • 6 月 25 日举办了『高压下的架构演进』专题活动,进行了闭门私董会研讨及对外开放的四个专题的演讲,期望能促进业界对应对峰值的方法及工具的讨论,本文是洪泽国介绍滴滴在 passport 设计的高可用经验。 洪泽国,...

    导读:应对高可用及极端峰值,每个技术团队都有自己的优秀经验,但是这些方法远没有得到体系化的讨论。高可用架构在 6 月 25 日举办了『高压下的架构演进』专题活动,进行了闭门私董会研讨及对外开放的四个专题的演讲,期望能促进业界对应对峰值的方法及工具的讨论,本文是洪泽国介绍滴滴在 passport 设计的高可用经验。

    洪泽国,2007 年硕士毕业于中科大,先后在 Oracle、腾讯等公司就职,主要关注在线服务的高可用、高性能和易扩展。

    大家好,我来自滴滴出行,今天其他老师分享的内容覆盖内容比较大,我分享的话题相对小一些,讲一个具体的应用。我们在 passport 设计时候踩过很多坑,后来在可用性方面做了很多优化实践,今天给大家分享其中的 7 个小优化。

    我的题目就指出了 Passport 设计的一切都是为了高可用。Passport 主要有两个功能,第一登录;第二,授权或者鉴权,每一个请求过来,我这边都会做一个校验,校验量是比较大的。再考虑到滴滴的场景,我们在座的大家可能是乘客端,但是我们还有司机端、代驾端等,司机端每一秒都会发请求过来,请求方就会到 Passport 请求一下,所以是一个典型的高并发高可用场景。

    业务场景

    先简单介绍一下业务场景,我来自滴滴平台部门,平台是一个业务支撑部门,支付、账号、消息等功能都会在我们平台里。今天主要给大家介绍账号子系统,我们设计 Passport,有很多优化的规则,比如大系统做小,做服务拆分,力度拆得非常小,目的是为了高可用。

    Passport 的应用场景,工作之一就是登录。登录成功之后返回 ticket,之后每一个业务请求都会把 ticket 传过来,如果合法,则返回给调用方用户真实的信息。

     

     

    Passport 简单理解,它是三元组。登录的凭证是手机号码、密码、UID,可以简单理解为 Passport 只维护了三元组。

    在我们开始设计一个账户,用户其他资料一开始揉在一起设计,后来我们发现这个问题非常麻烦,可用性会存在一些瓶颈,因此把大系统做小,把 Passport 单独拆出来,只包括这三元组。

    一切为了高可用

    我的第二个分享内容是一切为了高可用,我们做了什么?我们会从编程语言上,最早用 PHP 写的现在用 golang。最小闭环,柔性降级,异地多活,访问控制,接口拆分等。

    1. 选用什么编程语言

    我们编程语言是 PHP,现在账号系统用 golang,提升非常明显。有一个例子,一个乘客的用户服务,在线上布了 45 个实例,司机端或者乘客端都有心跳,每一个端有点像 ddos 攻击一样,不停的轮询,司机要不停上报他的状态或者坐标等等信息,访问量非常大。一开始用 45 台 PHP,后面用 golang 重写了一下,只用 6 台机解决了这个问题

    2. 最小闭环(大系统小做)

    刚才也说到用户的资料包括 count、UID、密码、名字等信息,我们把它做了一个拆分。拆分有什么作用?和我之前在腾讯的经历有关系。之前在腾讯的时候,老大一直说 QQ 永远不能存在不登录情况下,即时登录进去都是空白都能接受。这个的确有很大的差异,当用户不能登录,他以为他的账户被盗了,这会形成很大的惶恐,但登录之后什么都没有,他知道肯定是系统挂了,不会有恐慌的心理。因此对于帐号系统来说,需要永远要保证它是能登录的。

    最小闭环刚才说了,passport 只包括三个最主要的属性。我们乘客端刚刚上了密码登录,司机端都是用密码登录。在 QQ 时登录量是非常大的,校验量非常大需要做很多细致的工作。腾讯包括微信的架构都有一条经典的经验,大系统小做,当你把系统做小之后,高可用性最容易做,每一个功能比如用户存储的信息越多,这个事情就越难一些。

    (小编注:在上一篇大促系统全流量压测及稳定性保证——京东交易架构分享文章中,京东商城的杨超将这种设计方法叫异构

    3. 柔性及可降级之 Ticket 设计

    很多公司都需要降级,在柔性降级里面举几个例子跟大家分享。

    在移动客户端应用,登录时间通常是很长的。比如大家用微信,不需要经常登录,但是服务端需要有踢出用户的能力。踢出是什么概念?登录后,可以用另外一个手机登录就把前一个踢出,这样应用就会更安全。就因为可踢出,实现就会稍微复杂一点。

    我加入滴滴之前已经存在一个 Passport,最早是 PHP 语言写的。在滴滴合并快的,我也了解快的那边的情况,大家在设计 ticket 时比较简单和类似,一登录,生成一个 ticket,业务来请求提供认证,认证服务和 ticket 进行对比,对的就通过,不对就让用户踢出。

     

     

    我相信很多帐号系统都是这样实现,但这里面隐藏比较严重的问题。ticket 是无语义的,里面没有任何信息。其次如果 ticket 服务不稳定校验就会不通过,所有的业务请求第一步就是来校验,它对系统的要求,第一是低延时,你得足够稳定足够快。第二,不能有故障,一旦你个服务失败,用户端就会请求失败,就叫不到车。

    在滴滴,不管基础组件比如 MySQL 都需要考虑失败的情况,和滴滴快速成长有一定的关系,所有业务系统,在实现时就需要充分考虑系统的不可靠性。

    于是我们对 ticket 重新进行设计,下图是目前的设计。第一我们 ticket 增加了语义,里面是有内容进行了加密。这里面提一点,加解密尽量不要用 RSA 非对称算法,那会是一个灾难。ticket 里面包含一些信息,包括手机号、UID、密码。

     

     

    图上面有一个 seq,可能是我们这边比较独特的设计,你要实现可踢除,就像前图更多是对比两个 ticket 是不是对等,ticket 比较大是一个串,放在一个存储里面,空间挺大,并且不停地变,我们想把它改造成 seq,一个四字节的 int,通过 seq 达到 ticket 踢除的目的。

    在用户登录的时候发 ticket,ticket 有 seq,跟手机号加密在里面,每登录一次我会 seq + 1,我们有状态的是 seq,由很长的存储变成 int。我们验证 ticket 是否有效?只需要解密,把 seq 拿出来,跟数据库 seq 对比是不是一样?一样,就过了。

    这个项目我说了几点。第一,我用 token 的概念,实际上是没用,把它干掉,通过有状态的 seq 做到。另外,ticket 里面是自己包含内容是有语义的,这为我们降级各方面做了很多的探索,我们在降级的情况下会牺牲一点点的安全性。刚才说 Seq,由 ticket 变成 seq,存储下降非常多。

    这里实例说的还是柔性降级,假设 seq 存在 cache 里面,cache 这一级挂了,我们还是能够做到验证 seq,能解密,seq 判断符合要求,在降级的情况下也是可以过的。当然这也牺牲了一点安全性。

    4. 柔性及可降级之短信验证码

    我们最早大部分登录使用验证码,另外我们系统有很多的入口,我们在腾讯的微信、支付宝里面都有访问入口。在 Web 环境下系统很容易被攻击,后面我会讲攻击的事情。

    登录时候,输手机,发验证码,输入验证码,然后到我这边服务端做校验。通常做法也是用户点获取验证码,验证码有效期几分钟,系统存储一个手机号跟 code(验证码)的关系,登录的时候把手机号跟 code 传进来。

     

     

    验证时候根据手机号找到存储里面 code,两个一比,相同就通过了。但是也有问题,假如 cache 挂了,登录不了就会很被动,如何实现高可用?

    Cache 复制永远高可用是另外一个话题,我们尝试了另外一种柔性可用的方法。我们的需求是验证码能够在几分钟内有效,我们也可以计算,手机号加上当前时间戳,实际是 unix seconds 变成 unix minutes,算当前是多少秒分钟。通过手机号加时间,在它发的时候算 code,输入就是手机号加 unit,输出给它一个 code。

     

     

    第二步,用户输入手机号传过来手机号加 code,假设配置是 5 分钟有效,计算其中的时间,拿手机号加上当前的时间,假设是 5 分钟,递减 5 分钟,当前的分钟数和手机号算一个值与 code 对比,不对的话最多循环五次(当然这个也有优化之处)。

    当极端情况 cache 不可用的时候,我们可以手机号以及时间,通过内部的算法算出验证码是否基本可符,降级之后安全级别会一定降低,在可用性和安全性方面取得一个折衷。(编者:假如在系统正常情况下,cache 的验证码可以通过算法再加一个随机因子,严格符合才能通过,这样正常时候安全级别是可以有保证。)

    攻击者有两种攻击,一种拿着手机号,换不同的 code,这是一种攻击。另外一种攻击,拿固定的 code 换不同的手机号,我们现在结合的方式,我们现在还是采用第一种,当我们后端服务不可用,还有兜底方,当然牺牲了一点点安全性。当我挂掉那段时间,我还是照样可以登录。

    5. 高可用与异地多活

    讲一下异地多活,保证系统永远可登录。在滴滴,由于业务发展太快,下图是当前业务分布的情况,它带给我们的一些麻烦。

     

     

    上面是当前 Passport 简单的图解,我们现在是有 3 IDC,每一个 IDC 里面部署不同的业务,我们滴滴还没有做到业务异地多活。可能 IDC1 有专车快车,IDC2 有顺风车,IDC3 里面有代驾。

    我们现在是租用的机房,一个 IDC 如果机器不够用,就从别的机房匀出一些,导致我们的业务非常分散,这也给 Passport 和账号团队的服务提出挑战,我们要提前业务做异地多活。但是现在业务本身并没有做到异地多活。

    我们把登录实现了多活,注册还没做,但是目前已经足够满足我们要求,如果一个机房挂掉只是影响新注册的用户,在一定程度是可以接受的,所有其它的服务可保证正常使用。

    刚才提到不同的 IDC 存在不同的业务。一个人登录进来,先用快车在 IDC1,点开顺风车在 IDC2。这里面就有一些很细节的东西,也就是刚才说 ticket 问题。用户用户在 IDC1 登录,IDC1 给他一个 ticket,这个时候 IDC2 里的 ticket 并没有更新,因为我们所有的请求都是在同机房完成。这时候切到另外一个 IDC 校验,如果当前的 seq 比它传过来,而且发现比他当前小的情况,可以考虑放行。这是由于有可能同步的延迟,seq 还没同步过来。通过这个柔性可用策略,一定程度解决了多机房数据同步不一致的问题。

    6. 独立的访问控制层——Argus

    我们部门所有的服务都是平台级的业务,比如账号支付,所有业务线都要访问,一般都是通过内网来访问。

    为什么要做过载保护?当公司业务部门增多后,会碰到不同的业务拿到线上做压力测试的情况,我们现在所有的公共业务部署,不是按业务线多地部署,我们是大池子大集群,每个业务线都来混合访问。账号访问由于容量比较大,一般压测并没有引起问题。但是在支付的时候,做压力测试在线上支付,就可能会直接把支付拖挂。

    我们想必须有一种机制,不能相信任何的业务方,它随时能犯错误,需要通过技术手段去解决。因此需要有过载保护,包括权限控制等一系列机制等。

     

     

    如上图,防控就是 Argus 系统,承载了过载保护,白名单、安全策略等等职责。它是独立的服务,所有的业务流量打过来,都需要通过它做过滤。

    上面提到现在业务并没有多机房的部署,因此如果需要对调用方进行 QPS 的限制?只需要通过在 cache 里设置一个配额,每调一次检验一次。

    但这样有个问题,调用量太大。比如说快车有千万级别调用,调用量比较大,我给快车的某一个核心业务一个配额,如果都放在单个实例是支撑不住。因此可以增加一个简单的散列的方式,比如每个调用方调用的时通过 hash 到不同的 Argus 节点上。比如配额是十万 QPS,则可以部署 10 个节点,Argus 每一个就是一万,这样访问就比较可控了。

    7. 接口拆分

    刚才说的核心登录功能,不经常变,我们希望最稳定的接口独立出来,目的是让稳定不变更的部分故障率降低,所以需要考虑进行拆分。

    核心的接口包括登录这一块,其实不经常变,但是像一些小逻辑,策略会经常跟着去上线,但大部分事故都是上线引起的。

    分享一个 Pass-TT 的案例。当时跟快的合并时候,快的所有业务在阿里,滴滴所有的服务在深圳腾讯机房,ticket 服务在内网,两个机房跨公网,改造太大了,并且延时不可以接受。

    所以我们设计了一个方式,简单说,登录从我们这边登录,访问快的服务的时候再给它 ticket,token。这个 token 专门为代驾用的,但是设计时候犯了一个错误,就是 RSA 方式进行加密。因为有一个远程校验,为了不想 key 泄漏,所以用 RSA 的方式,他们那边部署了一个公钥,我们这边是私钥,token 用我们的私钥加密,然后到它那边进行解密就 OK 了。

     

     

    这些 token 失效是通过有效期,就是几个小时,失效后就用 ticket 来换。

    结果一上线,由于端上有一个 bug,然后所有的等于 ddos 攻击一样,不停闪。当时 Passport 服务器还比较少,10 台左右的服务,正常 CPU 利用率大概在 30% 不到,那个接口一上一下子到 70%,眼看全要挂了,然后连夜我们赶快把那样一个接口单独拆出来,打到不同的单元上,然后重新部署。

    所以给大家一个建议,当用 SOA 的时候,如果你的量特别大的时候,你一定要记得把它的 CPU 占用非常高那些功能及接口提前单独拆分出来。

    高可用的效果

    更多得益于 golang 本身,我们去年在线单机 QPS 峰值超过一万,现在我们有更多的机房,滴滴整个的订单去年和今年都是有数倍增长。

    我们响应时间,我们的所有接口无论获取用户信息或者是校验,其实是非常小的,目前高并发接口小于 5 毫秒。密码相关的接口是在 200 毫秒,这主要加解密本身的耗时。

    总结

    滴滴跟前面分享的今日头条非常相似,发展太快,四年的时间,滴滴的技术规范完全没有统一,文嵩加入滴滴之后,有机会再做服务治理包括框架统一,但是这件事可能会比较挑战,目前滴滴的技术体系特别异构,PHP、Java、Golang 都有,因此目前也不能太多从系统层面给大家做分享,以后应该有这样的机会。

    后面有一句话,什么是一切为了高可用?针对 Passport 账号这种系统,需要有柔性的降级,可能需要一些巧妙设计,包括多机房。

    one more thing

    被攻击的问题

    再补充一个被攻击的问题。其它的系统被攻击相对好一点,账号给你挡了,登录后再攻击,至少有 ticket 给你挡了。

    发短信攻击,这个维护费用是非常巨大的,攻击者目的你并不知道,他就是要你不停发短信,曾经被这个东西搞得焦头烂额。

    当然可以做一些蜜罐的机制,当发现有异常,返回正常值,让攻击者觉得正常,其实服务端什么也没做,这是蜜罐机制。要真正解决这类问题,跟安全部一起做了试点,端上做这种是比较简单,认证比较容易。但是在 app 上不好做,通过 JavaScript 算,其实比较麻烦,并且容易别识破。另外还可以做一些人机识别机制。

    Q&A

    Q:token 什么时候更新?

    洪泽国:token 只有两种失效机制,一个是用户重新登录,第二个踢掉,现在参照微信的做法,端上定期会拿着来换一次。

    Q:密码更新,所有的 token 都失效 如何解决?

    洪泽国:密钥一更新,登录都踢出?这个问题之前的确有讨论过,有两种方式,第一,让它失效,所有人重新登录,并不是完全不能接受,对用户来讲就是重新登录,密钥泄漏是一次事故。第二,看紧急程度,当前哪些人登录,比如先把没有登录的踢掉,后端算出来,对于已经有的,然后慢慢踢。新的在入口的时候,就要给它打到新的一套服务里面去,你要做新老两套密钥服务之间的切换,并且在上线是知道。

    Q:HttpDNS 作用?

    洪泽国:HttpDNS 从入口层面上就决定了所有的这一个请求全部落在这个机房,而不会存在两个 IDC 之间内部错峰的一切交替,不会你这个故障某一个服务我就打到那边。HttpDNS 比较简单,维护的信息比较少。无非就是一个服务对应一个IP列表,这是动态,这是很容易做的,信息不会太多。

    Q:切换 IDC 怎么做,数据你怎么复制?

    洪泽国:我们的确在讨论这样的方式,我不太确认是不是能够最完美回答你的问题,我们现在方案通过 HttpDNS 做中转,通过它我能够完成这件事情,第二,怎么发现故障,这里面包括两个问题,一个是怎么发现 IDC 挂了。第二,发现后怎么做,发现后 HttpDNS 很容易给一个新地址。第一个问题怎么发现,我们内部也在尝试一些方法,可能更多通过手段的方式,或者通过检测链路故障,无非触发时机,所有的链路故障都是从系统,网络层面上触发的。只要 HttpDNS 提供一个接口,一旦故障给它打个标记,A 故障,HttpDNS 就返回 B,这是很容易做到。但是怎么判断它是故障,这是一个问题。这个更多从网络层面去触发。

    Q:刚才说如果其它服务链路问题导致 Web 失效,把用户踢下去,对于这种情况你们怎么处理,不是你本身的问题。

    洪泽国:这个是调用方有约束的,调网络错误不应该是提的,更多是要从业务层面上,端和业务系统的配合形成。它调一个业务,业务调我,业务调我超时了,现在好多业务处理不是那么完美,出错也踢掉这是不合理的,我们跟他梳理,只有失效踢出是最合理。如果没有的话就踢掉,短信服务提供商那边压力是比较大的,做柔性降级。、

    转自:http://weibo.com/ttarticle/p/show?id=2309403993428869421583&luicode=20000061&lfid=3993428872483385&featurecode=20000180

    展开全文
  • 导读:本文主要以点评的交易系统的演进为主来描述如何做到高可用,并结合自己的经验做些分享。高可用性只是一个结果,要更多地关注迭代过程,关注业务发展。业界高可用的目标是几个9,对于每一个系统的要求是不一样...
  • 1)高可用:举个单机房高可用的例子,你肯定不希望因为一个磁盘损坏,或一个机器损坏,或者一个交换机损坏,就导致整个系统服务不可用了。 2)在系统容量增长情况下,如何实现可伸缩。 3)偏管理方面:...
    1. 分布式架构要解决的主要问题

    1)高可用:举个单机房高可用的例子,你肯定不希望因为一个磁盘损坏,或一个机器损坏,或者一个交换机损坏,就导致整个系统的服务不可用了。

    2)在系统容量增长的情况下,如何实现可伸缩。

    3)偏管理的方面:如果能够让7--10人的小组的工作是独立的服务单元,各个小组之间的工作有比较清晰的边界,这样他们合作起来会方便很多。

    4)服务质量:有南北方机房,让北方的用户访问北方的机房,南方的用户访问南方的机房,如果你有合适的机制能够让这些用户的所有的操作都能够整合起来,当做一个网站来用,这就是用多机房来提高服务质量。

    5)更高的需求:如果机房突然毁掉怎么办?如果你的业务是关键业务,你肯定希望做到能跨机房可用。

    今天主要讲前两点,单机房的高可用和可伸缩的问题,对常规服务我们怎样解决。


    2. 什么是高可用和可伸缩

    1)高可用:狭义来讲,单台机器宕机后,用户全无感知。从延伸来讲,不仅有机器的概念,还有各种设备,包括主机、网卡、交换机、网线这些都要做到用户无感知。还有,你可能部署了一大堆服务,可能某一个单个服务也会产生异常,比如打开的连接数过多,也许机器的CUP突然升高导致服务劣化。

    2)可伸缩:当业务量增涨的时候,如果能做到业务量增涨的时候只需要买了机器放上去,软件一部署,系统容量就增长了,这就是可伸缩。

    今天,我简单把系统分成四个层次,分别将他们的高可用和可扩展方案。
    1)入口处,也就是Nginx这个层, Ngx, apache这种层面的东西
    2)业务层
    3)缓存层
    4)数据库层

    3. 高可用问题的解决方案
    1) 入口层:
    入口层的高可用性,用的就是心跳,Keepalived就提供这个功能。
    注:Keepalived: Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。
    Keepavlied工作原理:ping, 监听端口,监控用户设定的服务器程序运行是否正常
    Layer3,4&7工作在IP/TCP协议栈的IP层,TCP层,及应用层,原理分别如下:
    Layer3:Keepalived使用Layer3的方式工作式时,Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包(既我们平时用的Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。
    Layer4:如果您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP端口的状态来决定服务器工作正常与否。如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。
    Layer7:Layer7就是工作在具体的应用层了,比Layer3,Layer4要复杂一点,在网络上占用的带宽也要大一些。Keepalived将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则Keepalived将把服务器从服务器群中剔除。

    比如说简单的做法,我们用两台机器做互备,一台机器的IP是1234, 一台是1235,那么我们再申请一个IP1236, 我们称之为心跳IP. 这个心跳IP平时绑在机器A上,如果A宕机了,机器B就主动把这个IP抢过去,那么就达到了A宕机了B补上去,B宕机了A补上去,这只需要做一个简单的事情,把DNS直接绑到1236上面,用户根据域名访问你的服务,你的服务只想一个心跳的IP,不管你哪台机器宕机了,这个心跳IP都是活着的,这样至少在入口层我们不用担心机器司机造成的可用性问题。

    Keepalived有什么使用限制呢?
    第一,两台机器必须在同一个网段,由于路由的原因,跨网段不能抢这个IP, 路由不到。
    第二,是服务监听,无法通过监听单个IP来绑定多个IP, 因为IP的监听必须是对称的。最简单的做法是,你就全部监听所有的IP.
    第三,服务器的利用率会下降,因为是主备模式,本来一个机器可以1000M,你可能觉得两个机器可以抗住2000M流量,可实际上2台机器还是只能1000M。

    2)业务层:推荐采用无状态,即不适用进程内缓存。-- 貌似扯淡,不用缓存怎样保证高性能。
    业务层不要有状态,状态要分散到缓存层和数据库层。当我们用Java的时候,把很多技术线或者其他东西扔到内存里面,这样会导致整个业务的状态会嵌在业务层里面,那么如果这台服务器死机了,里面的数据就丢掉了(在融云,通过redis/ssdb保证缓存的数据在宕机后不丢失)。第二,如果你没有状态,签名是一个接入层,nginx,后面是多台业务服务器,那么一台业务服务器只会通过反向代理,把剩下的流量达到剩余的服务器上面去,如果这台服务器宕机了对用户来讲是完全无感知的。

    3)缓存层:
    缓存层做高可用直接做成本很高。最常见的做法是,把缓存层分得足够细。比如我们只有两台机器当缓存,其中一台宕机了,我们就会有50%的请求直接压到数据库,数据库可能就直接宕机了。如果我们把缓存的规模分的比较细,我有10台机器,每台只有1/10的容量,那么宕机一台,数据库的请求量比总量要增加10%,增加10%对数据库来讲就更容易承受。我比较推荐把业务层和缓存层混合部署,即业务层部署10台机器,缓存层也部署10台机器。就是说,缓存天生是没有高可用问题可言的,唯一要担心的是,一旦缓存宕机,会不会把数据库压垮。
    对于某种特殊情况,即时缓存分散,也是无法容忍的,最简单的办法是缓存启用主从两台,主服务器活着的时候,从主服务器读,主从服务器都写。主服务器宕机的话,从服务器升级为主服务器,主服务器恢复之后变成新的从服务器。这样可以保存缓存的数据依然有效,这种模式的变种比较多,大多数需要两倍的服务器。
    我也见过1.5倍服务器的情况,A服务器做一部分缓存,B服务器做一部分缓存,C作为A和B的异或。A宕机了,B和C也可以用。

    4)数据库:
    数据库的高可用性来讲,在业界的产品层面都解决得差不多了,SQL这一些列的,例如MySQL,有主从模式,有主主模式,都可以满足需求。


    4. 可伸缩问题的解决方案
    1)入口层:
    最简单的,直接加机器,机器放多一点,DNS加上IP, 访问的时候自然都某个IP上去了。
    简单加机器不能说不行,但有一个问题,域名解析这个阶段是不保证的,一个域名解析到10个IP,那是均匀的,但绝大部分域名解析服务器根本无法做到这一点,你会发现大部分请求只会使用前面几个IP,然后这个优化效果就很不稳定。所以如果你真的流量大到你的入口都扛不住了,最简单的就是你的入口用一些比较大的服务器(比如融云的CMP),比如说以前你有千兆网,那上万兆,现在也不贵,上万兆不行再上40GB, 百GB的服务器现在也是比较成熟的技术了。业务服务器就隐藏在内网,隐藏在内网之后,这是一种方式,如果你是基于HTTP的话。如果非HTTP,经常有一些客户端,比如游戏客户端,那么在客户端做一个调度,客户端访问之前先去一个小的服务器问有哪些IP可用,你拿到入口之后,再随机挑一个,这样也能做到比较均匀的调用。

    2)业务层:业务层的可伸缩,只要保证无状态就好了。

    3)缓存层:
    缓存层的伸缩性,redis3.0解决了这个问题。如果想自己搭,最简单的解决方式是,如果低峰期间,比如半夜2,3点,数据库能抗住,那么直接把缓存下线掉,再上一个新的缓存系统。扛不住的话,比如是个国际站点,整天都没有低峰时段,或者说确实数据库不是设计了能抗住无缓存压力的话,我们把缓存分成三种类型,第一种是强一致性缓存,也就是说,我们无法接受从缓存里面拿到错误的数据,比如缓存用户余额。第二种是弱一致性缓存,只要达到最终一致性就可以了,能够在接受一段时间内从缓存拿到错误数据,比如微博的转发数。第三种是不变型的缓存,也就是说缓存这个key对应的值不会变更,比如我们要做解密工具,从SHA1反推密码,这样的结果不会变,或者其他复杂公式计算结果。
    这三种缓存的处理方式不同。
    若一致性缓存和不变型缓存扩容比较方便,用一致性hash就可以,强一致性情况会稍微复杂。比如,我们的业务服务器回去缓存系统取数据,至于这个缓存系统的配置是9台还是10台,是有一份配置文件保存在业务服务器里面的,如果你要更新缓存服务器配置的时候,你要通知业务服务器去修改这个配置,这时会有个微小的时间差,导致拿到的是过期的数据。第二种情况,你有可能扩容,扩容之后你再删除节点,比如你发现缓存出问题了或者有其他问题,这时候会拿到脏数据,比如A的key之前在机器1, 扩容后再机器2,数据更新,删除机器2后Key回到机器1,这时候会有脏数据的问题,这样比如用特殊处理把这个问题解决掉。
    最简单的办法是只增不减,这当然意味着我们要引入一些高可用的技术避免单个节点坏掉。第二种方式,要么节点调整时间大于数据的有效时间,这样可以规避掉这一问题。

    4)数据库
    我们常用的几种办法,
    办法1. 水平拆分,比如用户量比较大,预先根据用户的ID拆分成100个表,临时往一台机器上面装,未来可以扩展到100台机器上去。
    办法2. 垂直拆分,典型的案例是一个电子商务网站,每个商品有一些最基础的信息,最后还有一个非常详细的信息页面,如果把信息页面和之前的信息存放在同一个数据库,那么取这种简单的基础信息的时候,也会把详细信息带出来,带出来的话,整个取的效率就很低。那么你把详细信息分到单独的表里面去,签名的索引,数据库大小都可以缩,相当于你的性能提高了。
    办法3. 你可以做一些定期滚动,比如交易记录,要看之前记录的话需要做查询。这样对应的交易日志可以把三个月之前的就滚动到一个更大的数据库里面去了

    总结:
    把业务系统分成几个层,入口层、业务层、缓存层、数据库层。在这几个层里面有不同的技术去解决高可用和可伸缩的问题。比如入口层,用心跳解决高可用,用平行部署解决可伸缩。业务层很简单,千万记住,不要有状态,至少没有状态的时候,这两个问题解决很简单。缓存层,第一是减小粒度,避免对数据库的冲击。要么用redis3.0, 要么用一致性hash, 把伸缩带来的冲击降到最低。数据库,一个是主从模式,一个是水平或垂直拆分与定期滚动。

    最后讲一下,我们不一定要到一定规模的时候采取考虑高可用和可伸缩的事情,因为高可用和可伸缩,对于大部分架构师来讲,这个东西成本并不高。比如一个简单的这种模型的业务服务,简单的一个前端业务和数据库模型,我们简单的用两台机器就可以达到所有的高可用和可伸缩的配置。最开始两台机器完全一样的部署,前面一个Nginx,两个配心跳,中间是业务,最后是数据库,一个主一个从。当业务量逐步增加的时候,第一步把数据库分出去,第二步把业务和前端做一个分离,第三部业务层做水平伸缩,第四部加缓存层。不要认为业务量小的时候就随便搭,真出了篓子就不太好了。比如某app在大访问量的时候没有抗住,这时候客户就流失掉了,再要把客户找回来就不容易了。作为一个负责任的架构师,你先把这个东西搞定掉,既然成本不高,干嘛不先搞定?
    展开全文
  • 演讲视频演讲实录:下面开始我们今天主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。首先介绍一下什么是高可用?在我看来就是业务在高质量情况下,对用户提...

    作者:王甲坤,腾讯高级工程师、腾讯云关系型数据库MySQL负责人,拥有多年客户端、数据库研发经验。在IOS客户端、MySQL、PostgreSQL、SQL Server等产品有丰富的研发和产品策划经验。

    a493c1da80c0e27e41eae7b0cf037611.png演讲视频

    演讲实录:

    下面开始我们今天的主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。

    9de6dda9adf0d997177129f5ad9b1355.png

    首先介绍一下什么是高可用?在我看来就是业务在高质量的情况下,对用户提供服务的可运行的总时长。其实我们从事MySQL相关的工作,大家对9这个数字比较敏感,大家选择云厂商云产品的时候,首先会看它的数据库有几个9。目前腾讯云MySQL可以做到99.95,全年在25分钟的样子。

    据我了解,高可用最高是能做到3个9,1个6,做到4个9很困难,做到5个9就是极限了。

    b4b5b976b4ac727199bbb7a07d72dd80.png

    为什么我们要做高可用?因为我们不可控的因素太多了,比如说,挖挖机,我记得基本上每隔一年都会出现这种类似的事件,让我记忆犹新的是2015年杭州萧山的某个主干网被刮断,导致阿里的部分服务不可用。另外,还有类似的一些停电,或者一些天灾等等。值得一提是,运维人员的一些操作失误案例,rm整个目录或者drop表,民间有说法叫从删库到跑路。不可控制的因素很多,你的数据、用户是你的,如果不可控的话,你的业务上不去。

    a92054177a6d74651f665a1a5a7befff.png

    一般来说,有两个指标会被当作衡量的标准,第一是RPO,第二是RTO。RPO从故障开始到业务恢复所丢失的数据量,RTO就是从故障开始到业务恢复所耗费的时长,两者都是越短越好。

    我们怎么做呢?一般来说业界有三种方式,左边是基于单机存储方式,这种方式在游戏场景比较多,大家上层是用单独的计算机节点,下层用三副本保证数据的可靠性。在计算节点发生故障以后可以快速迁移到另一个计算节点,当然我们腾讯云的MySQL已经推出了这种模式,相对来说非常廉价,是基础版,大家在官网都可以购买到这种模式。第二种是基于共享存储方式,也叫share disk模式,这种比较典型的是oracle的RAC架构。底层基于共享存储的方式,上层采用多个计算节点,某个计算节点故障可立即从ip列表中提出,不影响用户访问。第三种就是基于数据复制模式,也就share nothing模式,通过数据传输、复制协议达到两台主机数据一致性,也是本次讲解的重点。另外,除了存储节点的高可用,其整个链路也需要高可用,比如,咱们的IDC机房,交换机,以及主机服务器等。

    8639022fed4785305fcec461cd65ad5f.png

    下面我们介绍下基础设施的高可用。大家经常听到几个术语,第一是同城双活,第二是两地三中心,两地三中心对于金融相关的场景是个强需求,其实说白了就是说我们在同城两个节点相差十公里之外有两个数据中心,在100公里异地以外有另个灾备中心,保证了机房的高可用。另外包括网络、主机,其实架构上是这样的,至少说你的交换机网络都有备份,一个倒了以后,另一个需要替换上去。

    d60a7f4800e5b3d53eb1818886cb9d2b.png

    下面进入我们的重点,基于数据复制的高可用,首先介绍一下备份,备份确实是非常重要的,而且备份是一个实在没办法最后的一个保障,所以说建议大家不管是在云上用的业务,还是自己的IDC尽量做好备份。

    MySQL备份基本上是这两种:逻辑备份、物理备份。逻辑备份通常使用官方的MySQLDump与第三方工具MyDumper,MyDumper优势在于多线程备份,速率快。物理备份使用Percona的xtrabackup,可以不落盘,通过基于流式并发与压缩,生产出成功率较高、速率较快并且暂用存储空间较低的备份。最后一种就是快照,我们腾讯云的基础版的备份就是通过快照生成的。

    那基于数据复制方式,一般是主从两个节点,数据怎么保证一致性呢?其实是通过复制协议进行数据传输,通过Switch切换保证故障以后服务能够尽快恢复。右边的图基本和腾讯云MySQL差不多的架构,我们采用了一主一从的方式,从节点只负责故障的转移,当主节点挂了以后,通过自动故障探测与自动切换,从而做到业务尽快恢复。另外针对读写分离,腾讯云MySQL现可以支持一主挂5个只读节点。

    下面介绍一下复制,在介绍复制之前有必要介绍一个重要的概念:binlog,binlog是二进制文件,主要记录用户对数据库更新的sql信息,binlog是什么样子呢?它是在磁盘上是这个样子,使用show binlog events后它是这样的,里面会记录一些元信息,比如位点、事件等等,我们通过MySQL官方解析工具mysqlbinlog解析后是这样的,里面sql语句是使用base64编码的,解码后是这样的,可以看到这里是条插入语句。那什么时候写binlog呢?大家来看这个图,我们知道事务提交有两个阶段:prepare与commit,请问是哪个阶段写binlog呢?binlog其实是在prepare后commit前写入的,同时写事务过程中,会产生redolog与undolog,那这两者有什么区别呢?我们知道MySQL是多引擎的关系型数据库,binlog是MySQL Server层的日志,而redolog是MySQL引擎InnoDB层的日志;另外一个不同是两者写入时机不同,redolog是prepare阶段每执行sql语句就写redo了,而binlog是在prepare完commit前写的。那MySQL在主从架构下怎么保证数据一致性呢?众所众知,MySQL为了保证性能,数据是先写内存后落盘的。当你数据库运行的时候,发生了宕机,机器再次恢复的时候可能是部分数据落盘了,部分未落盘。这时,mysql是找到binlog最新同步的位点或GTID,来确定redolog或者undolog中哪些实例需要回滚,哪些事务需要重做。另外,在写日志的时候,比如redolog或binlog,MySQL为保证高性能,也是先写内存后落盘的,所以日志的落盘策略也会影响数据的一致性。为保证数据的一致性,建议大家将涉及日志的参数配置为“双1”,也就是如图上所示。

    ea6eadd25b9ad342f1301caa5aa20e71.png

    下面我们来看看复制整个流程,其实很简单,Master通过dump线程将binlog落盘,在Slave上会有两个线程,分别是IO线程和SQL线程。IO线程接受来自Master的binlog并落地形成Relaylog,SQL线程并行读取relaylog中的sql信息,执行回放动作。一般来说, 复制分三种:异步复制、半同步、强同步。这三者的区别在于何时将sql执行的结果反馈给客户端。异步复制,Master不管Slave,Master执行sql完毕后立即返回给客户端,这种方式性能最好,但是存在数据不一致的可能;强同步呢,Master完全关心Slave,等待Slave将relaylog回放后才返回给客户端,这种方式能够保证数据强一致,但是其性能有一定损耗;半同步则是Master部分关心Slave,认为只要binlog传输到Slave侧,落为relaylog后,即可以返回给客户端了。半同步是一种兼顾的实现,一方面保证数据一致性,另一方面兼顾了数据库的性能。

    ec297aaa822b476dbfc556be4d5184d2.png

    在复制过程中,我们经常遇到延迟问题,大家看图中所示,复制经历三个阶段:Dump线程落盘binlog、IO线程落盘relaylog、以及SQL线程回放,请问三个步骤里面哪个步骤是一个瓶颈?是SQL线程,是因为SQL线程在回放日志过程中是串行执行sql的,而Master对外是并行提供服务的。所以这里瓶颈是SQL线程。大家可用通过开启并行复制来解决延迟问题,MySQL5.6基于库级别并行复制;MySQL 5.7基于逻辑时钟并行复制,也就是表级别的并行;而MySQL8.0则是行级别的并行复制,粒度更细,复制效率更高。

    4fd52b14b262746ec9c1f8b753c7aab7.png

    刚才是说在协议级别进行复制,其实还有一种方式是块级别的数据复制,其不关心上层是什么,只需要保证在磁盘层面数据复制即可。当然这种方式的话,应用的比较少。说完复制后,咱们来说一下切换,其实MySQL官方之前并没有提供故障自动发现与转移的能力,基本上靠第三方工具来实现。

    c32fd7ec108bed4b23167f56ac6e8a3e.png

    第一种是Keepalived,Master和Slave相互探测对方,时刻询问对方存活状态。当出现网络抖动或者网络出现问题的时候,可能会出现脑裂问题,变成了两主,数据就写错乱了。第二种就是MMM的方式, M1M2互为主备,再加上一个Slave节点做冗余。从图上看,虽然是双主,但该模式下同一时间点下只能有一个节点可以写,当发现这个主写节点出现故障,会将vip切换到另一个主上比。整体看,这种方式比较老,问题比较多。第三种是MHA,其应用广泛,这种方式是由复制组与管理节点组成,每个复制组里是由至少三个数据节点组成,数据节点上部署监控agent,定时上报到管理节点,当主节点出现问题时,由管理节点裁决是否切换到从节点。腾讯云是自己实现了一套故障检测,结构如右边的图,由高可用保证的Monitor节点来进行故障检测与切换。另外,目前我们还在做MySQL高可用的重构,届时能够做到故障检测恢复30秒钟以内,大大提高了高可用。

    12804bccc5bbcd3fac6a8874fdf6a7c5.png

    下面我们来说下集群的高可用架构,比较有名的就是PXC、MGC、MGR,PXC和MGC是结构比较类似,MGR是官方提供的,具有故障转移的高可用架构。大体的层级是这样的,MGR以插件的形式存在的,MGR主要是把复制协议进行改造,因为MGR支持多活,所以这里另一个重点是冲突检测,若多个节点同时写同一主键时,依照哪个为准呢?MGR是采用基于Paxos协议实现的冲突检测。下面,我们大致看下结构,MGR是支持多个节点写,即多活,支持某个节点挂了后自动剔除,恢复后自动加入集群。这张图是介绍一下MGR数据流逻辑,图上有三个节点构成最小MGR集群。假设DB1有一次写提交,在Prepare阶段,MGR插件会生成一个叫WriteSet的集合,并将其广播给其他节点。这个WriteSet集合包含此次提交的binlog和更新的唯一键,此唯一键由db名、表名和主键组成。这里可以看出MGR有个限制,表中必须要有主键,要不无法进行冲突检测。我们再说回来当节点收到这一信息时,会进行比对,每个节点都有一个缓存,保存当前同步情况,即唯一键对应的GTID SET。通过比对后将结果返回给DB1,只要多于半数的节点返回说OK,可以提交,那DB1接下来就会执行binlog的落盘操作,然后返回OK到客户端。其他节点则执行写Relaylog的动作,接下来进行回放的动作。若多数节点返回冲突,DB1则执行回滚操作,其他节点会drop掉复制过来的binlog。

    其实PXC和MGC思路是差不多,应该说是MGR借鉴的,因为PXC和MGC是比较早就出来的,这里大同小异,主节点将WriteSet写集合广播出去,广播完后进行验证与裁决。

    ddf190fc92f982accde9faad74a09030.png

    最后我们说一下NewSQL高可用架构,首先对AWS表示致敬,孵化出非常优秀的NewSQL产品-Aurora。那Aurora是怎么产生出来的呢?这与AWS数据库架构有关。我们来看看这个图,AWS数据库是架构在虚拟机与云盘上的,我们都知道MySQL的log比较多,所以很多IO是通过耗时较高的网络来完成的,因此AWS这种架构网络IO是它的瓶颈,性能也跑不上去。在此基础上,我们来认识下Aurora。

    Aurora是计算与存储分离的架构,典型的share disk 的结构。底层存储采用6副本,部署在三个不同的AZ上,可以保证一个AZ挂了,或者至多两个AZ的一个副本丢失的情况下数据不丢失,业务可以正常对外服务。Aurora的理念是“日志即数据库”,其把MySQL存储层进行了彻底的改造,摒弃了很多LOG,只留下了Redolog,具备将redolog转换到Innodb page的能力。通过这种方式,Aurora宣称其减少至少85%比例的IO。另外其把备份和回档下沉到存储节点,使得备份恢复更快并得到保障。Aurora整体感觉相对比较接地气,成本相对比较低。

    另一个就是阿里云的Polar,理念和AWS不同,阿里云觉得未来网络不是问题,未来网络可以接近总线的质量,所以是架构在RDMA网络的机房里,日志方面大动作较少,保证后续MySQL社区新特性可快速迭代近来。Polardb也是share disk的架构,其存储节点是通ParallelRaft协议保证数据的完备性。可见这也是个伟大的架构,但是相对来说成本比较高一些。

    我们腾讯云自己的NewSQL在研发中,只是目前还没有正式上线,我们的名字叫CynosDB,相比来说我们的理念是兼顾两者,未来在高网络新硬件的基础实施下,会发挥更大的性能,更稳健的服务和更高的可用性。请大家拭目以待。

    本次我的分享就到此为止。

    Q & A

    Q:我想问一下在腾讯游戏的高并发行业里面,我们主要采用哪种架构?

    A:腾讯内部有很多自研项目,但基本上我们是基于数据复制的方式。内部有phxsql等分布式集群架构。

    Q:如何在高并发情况下,保证总库的定延时呢?

    A:可以开启并行复制,业务做分库分表,分散到多个实例上。

    Q:比如说像游戏类的,在游戏高峰期的话会有很多人同时在线,这种情况下怎么在后台看数据呢?

    A:可以对比较热的数据进行分层,前一层可以通过KV方式缓存,比如Redis,来提高热数据的读取,后一层使用MySQL,定期将数据同步落盘。

    Q:这种情况下怎么保证数据库是一致的呢?

    A:写数据可以不经过KV缓存,直接写MySQL数据库,读取时,缓存内没有数据,需要从DB中捞取出来。另外,KV缓存也有落地能力,非关键数据也可以不使用MySQL落地。

    你一定还想看

    《磊哥测评:自建数据库VS云数据库,到底怎么选?》

    《腾讯云自研数据库CynosDB存储架构揭秘》

    《腾讯云新一代数据库发布 企业“上云”成本大幅降低》

    《一图了解 TencentDB 的2018》

    《磊哥测评:腾讯云数据库 VS 阿里云数据库》

    《听云轻松处理日均千亿级数据请求量背后的秘密》

    2b9b55efc3a11afcef2724cc803e4f5f.png

    TencentDB

    云上智能数据管理专家

    ↓↓点此1元包月MySQL

    展开全文
  • 导读:应对高可用及极端峰值,每个技术团队都有自己优秀经验,但是这些方法远没有得到体系化讨论。高可用架构在 6 月 25 日举办了『高压下架构演进』专题活动,进行了闭...
  • 自我介绍冷正磊,2018 年 2 月加入去哪儿网 DBA 团队,主要负责公司 Redis 和机票业务 MySQL 数据库运维工作...前言本文主要介绍了 Qunar Redis 高可用架构设计原理、安全机制及集群自动化运维方面内容。Qunar R...
  • 本文主要以点评的交易系统的演进为主来描述如何做到高可用,并结合了一些自己的经验。需要强调的是,高可用性只是一个结果,应该更多地关注迭代过程,关注业务发展。 可用性的理解 理解目标 业界高可用的...
  • 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~...下面开始我们今天主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。首先介绍一下什么是高可用?在我看来就是业务在...
  • 王甲坤,腾讯高级工程师、...下面开始我们今天主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。首先介绍一下什么是高可用?在我看来就是业务在高质量情况下,对用户提供服务...
  • 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~...下面开始我们今天主要内容,今天主要是通过什么、为什么、怎么做,这条思路跟大家呈现MySQL的高可用。首先介绍一下什么是高可用?在我看来就是业务在...
  • 作者介绍冷正磊,2018年2月加入去哪儿网DBA团队,主要负责公司Redis和机票业务MySQL...本文主要介绍了 Qunar Redis 高可用架构设计原理、安全机制及集群自动化运维方面内容。一、高可用架构设计原理1、概述Qunar R...
  • 原文:https://www.cnblogs.com/lupeng2010/p/6519466.htmlPS:前段时间和Mentor们一起参与研发”百度地图百城千店感恩节AR游戏送大礼”后端项目,积累了一些并发情景下系统设计经验,这里统一抽象成【秒杀...
  • 推送系统的高可用性以及如何提高可用性 缓冲机制与服务解耦 无状态服务以及多机房部署 过载保护与分级机制 小米推送是目前国内领先推送服务提供商,主要为开发者提供快捷、准确、...
  • 近日在Qcon开发者大会北京站上,来自阿里巴巴商家事业部技术专家沐剑在专场分享了题为《高可用实践:从淘宝到上云的差异》的演讲,主要介绍了其近几年在阿里电商平台及阿里云上的高可用设计的经验,分为两个部分:第...
  • 高可用系统在点评实践与经验 大众点评 可用性理解频率要低时间要快几点经验基本是演进过程高可用的图。高可用是个结果。。频率要低MTBF: 更多从设计上,(业务-》组织结构-》架构)时间要快MTTR: 5分钟把问题...
  • 如何设计一个亿级流量高性能、高可用、高并发分布式系统?   面试题 如何设计一个高并发系统? 面试官心理分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶劲了。为啥?因为你没看到现在很...
  • 自我介绍冷正磊,2018 年 2 月加入去哪儿网 DBA 团队,主要负责公司 Redis 和机票业务 MySQL 数据库运维工作...前言本文主要介绍了 Qunar Redis 高可用架构设计原理、安全机制及集群自动化运维方面内容。Qunar R...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,003
精华内容 401
关键字:

高可用设计的经验