Py学习  »  分享发现

微博技术底层架构的实现

Py站长 • 10 年前 • 3111 次点击  

微博技术研化史

  • 第一版本的技术细节,典型的LAMP架构,是使用Myisam搜索引擎,它的优点就是速度非常快。另外一个是MPSS,就是多个端口可以布置在服务器上。
  • 问题:

    • 首先是推模式,这肯定是延迟的首要原因,我们要把这个问题解决掉。其次我们的用户越来越多,这个数据库表从一百万到一亿,数据规模不一样处理方式是有差别的。我们第一版单库单表的模式,当用户数量增多的时候,它不能满足就需要进行拆分。
    • 第二个是锁表的问题,我们考虑的是更改引擎。另外一个是发表过慢,我们考虑的是异步模式。
    • 第二版我们进行了模块化,我们首先做了一个层,做了拆分,最右边的发表做了异步模式。第二个服务层,我们把微博基础的单元设计成服务层一个一个模块,最大是对推模式进行了改进。首先看一下投递模式的优化,首先我们要思考推模式,如果我们做一下改进把用户分成有效和无效的用户。我们一个用户比如说有一百个粉丝,我发一条微博的时候不需要推给一百个粉丝,因为可能有50个粉丝不会马上来看,这样同步推送给他们,相当于做无用功。我们把用户分成有效和无效之后,我们把他们做一下区分,比如说当天登陆过的人我们分成有效用户的话,只需要发送给当天登陆过的粉丝,这样压力马上就减轻了,另外投递的延迟也减小了。
  • 我们再看数据的拆分,数据拆分有很多方式,很多互联网产品最常用的方法,比如说如可以按照用户的UID来拆分。但是微博用户的一个特点就是说大家访问的都是最近的服务器,所以我们考虑微博的数据我们按照时间拆分,比如说一个月发一张表,这样就解决了我们不同时间的惟度可以有不同的拆分方式。第二个考虑就是要把内容和索引分开存放。假如说一条微博发表的地址是索引数据,内容是内容数据。假如说我们分开的话,内容就简单的变成了一种key-value的方式,key- value是最容易扩展的一种数据。比如说一个用户发表了一千条微博,这一千条微博我们接口前端要分页放,比如说用户需要访问第五页,那我们需要迅速定位到这个记录。假如说我们把这个索引拆分成一个月一张表,我们记录上很难判断第五页在哪张表里,我们需要索引所有的表。如果这个地方不能拆分,那我们系统上就会有一个非常大的瓶颈。最后我们想了一个方法,就是说索引上做了一个二次索引,改变我们还是按照时间拆分,但是我们把每个月记录的偏移记下来,就是一个月这个用户发表了多少条,ID是哪里,就是按照这些数据迅速把记录找出来。

  • 异步处理,发表是一个非常繁重的操作,它要入库、统计索引、进入后台,如果我们要把所有的索引都做完用户需要前端等待很长的时间,如果有一个环节失败的话,用户得到的提示是发表失败,但是入库已经成功。所以我们做了一个异步操作,就是发表成功我们就提示成功,然后我们在后台慢慢的消息队列慢慢的做完。

  • 第二版我们做了这些改进之后,微博的用户和访问量并没有停止,还有很多新的问题出现。比如说系统问题,单点故障导致的雪崩,第二个是访问速度问题因为国内网络环境复杂,会有用户反映说在不同地区访问图片、js这些速度会有问题。另外一个是数据压力以及峰值,MySql复制延迟、慢查询,另外就是热门事件,比如说世界杯,可能会导致用户每秒发表的内容达到几百条。我们考虑如何改进,首先系统方面循序任意模块失败。另外静态内容,第一步我们用CDN来加速,另外数据的压力以及峰值,我们需要将数据、功能、部署尽可能的拆分,然后提前进行容量规划。
  • Google首席科学家讲过一句话,就是一个大的复杂的系统,应该要分解成很多小的服务。比如说我们在Google.com执行一个搜索查询的话,实际上这个操作会调动内部一百多个服务。因此,我们第三版的考虑就是先有服务才有接口最后才有应用,我们才能把这个系统做大。
  • 平台服务和应用服务是分开的,这样实现了模块隔离,即使应用服务访问量过大的话,平台服务不会首先影响。另外我们把微博的引擎进行了改进,实现了一个分层关系。用户的关注关系,我们改成一个多惟度的索引结构,性能极大的提高。第四个层面就是计数器的改进,新版我们改成了基于偏移的思路,就是一个用户他原来读的一个ID比如说是10000,系统最系的ID是 10002的话,我们和清楚他有两条未读。原来的版本是采用绝对技术的,这个用户有几条未读都是用一个存储结构的话,就容易产生一致性的问题,采用这种偏移的技术基本上不会出错。
  • 下面给大家介绍一下新浪微博怎么样打造一个高性能架构。到目前为止有五千万用户使用新浪微博,最高发表3000条以上每秒,然后一个明星用户发表的话,会被几百万用户同时读到。这些问题的本质是我们架构需要考虑高访问量、海量数据的情况下三个问题。易于扩展、低延迟、高可用和异地分布。我们每天有数十亿次外部网页以及API接口的需求,我们知道微博的特点是用户请求是无法cache的。因此面对这个需求我们怎么样扩展?几点思路。第一我们的模块设计上要去状态,我们任意一个单元可以支持任意节点。另外是去中心化,避免单点及瓶颈。另外是可线性扩展。最后一个是减少模块。
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/948
 
3111 次点击