mixi系统构成分析

   作者:张杰 
   时间:2006年7月 
   首次发表于这儿

下面的blog介绍了日本最大的SNS网站「mixi」的系统构成。
(据说是一个厉害人物写的)
http://blog.livedoor.jp/nipotan/archives/50538571.html [中译文]

 

作者:张杰
URL:http://spaces.msn.com/members/newbdez33/
http://www.phpboom.com/ 

本文将根据上面的blog内容进行分析,便于大家理解。
先补充一下关于mixi的MySQL分区的构成部分解释:

因为MySQL5.1的还在beta版,
所以mixi的DB构成只是利用分区的概念,
模拟进行DB布置。
他们的分区不依赖MySQL,
而是人工的把每个分区存放到不同的MySQL服务器。

______________________________________________________________
>■DB partitioning (DB scale)
> ?vertical partition - 纵向 (每个用户)的scale -
>  ?需要一次性作业时,实时的移行比较难。
> ?horizontal partition - 横向 (每个表)的scale -
>  ?对象是比较慢的表 (信息、日志等)
>   ?→ 取名叫level 1 、采取了这个方法
______________________________________________________________

以上部分分别介绍了
1.纵向分区,对mixi的每一个用户的信息进行纵向分区,以加快检索速度。
2.横向分区,把一些信息量大,日志等类型的表采用横向分区(应该是按时间这类的分区)
    他们把横向分区取名叫level 1

______________________________________________________________
>■到level 1 的移行手顺
> ?同时往OLD DB 和 NEW DB 里 write 、 从 OLD  read
> ?从OLD 到 NEW  INSERT (移行) 完了后、允许从NEW read
______________________________________________________________

以上部分讲的是level 1的DB追加节点或移用的方法。


______________________________________________________________
>■partitioning 的问题点
> ?不能 JOIN
>  ?取benchmark的结果是、比起JOIN、从应用软件调用两次更快,所以没有问题
______________________________________________________________

这里应该没什么问题,如果使用分区,一不小心就会顺手用上JOIN来连接,其实速度不怎么样。

______________________________________________________________
>■level 1 的问题点
> ?但是,光日志和信息等的 partitioning 就变得很慢
>  ?→ 采取了level 2 (vertical partition)
______________________________________________________________

这里是对采用了横向分区后DB再次进行纵向分区,以加快速度。

______________________________________________________________
>■level 2 的 partitioning key
> ?user id, message id 等
> ?如果 partitioning 细一点,性能tuning可能容易些,但partition map会变大
______________________________________________________________

partitioning key,就是分区字段设置,一按user id或message id分区,
把大的内容字段,比如user memo,message body等大字段分到另一个区。
这样才能增加检索速度。
不过如果分的太细了,在性能上更容易按我们的意愿调整,但parttion map,
即存放分区信息的内容会变大,下面讲partition map是什么。

______________________________________________________________
>■partition map for level 2
> ?不能简单地放到 configuration file 等
> ?manager base
>  ?写入DB
> ?algorithm base
>  ?如果用算法算出更新和参照的地址, read 和 write 将变成同样的节点
______________________________________________________________

概念上,partition map就是所有的分区信息(不管是横向还是纵向都需要),
从blog上写的,level 2不能简单的放到config文件中,可以了解,
level 1是放到config文件中的,因为横向分区的分区信息会比较少,
比如,按年份划分,就可以这么写:
db_pp_config.inc.php
----------------------------------------------
1999:10.0.153.71:log_part_1999
2000:10.0.153.72:log_part_2000
2001:10.0.153.61:log_part_2001
2002:10.0.153.32:log_part_2002
----------------------------------------------
这个文件就是一个分区配置文件,表示
1999年的数据放在71服务器的log_part_1999这个数据表中。

而level 2的因为是按字段进行分区,就不好放到配置文件中,于是就有了
manager base(基于管理),和algorithm base (基于算法)。
以下介绍这两种
______________________________________________________________
>■manager base
> ?比如,向manager DB 询问 user_id = 14 的节点地址
> ?优点
>  ?容易管理
>  ?容易追加新的节点
>  ?节点间的数据容易移行
> ?缺点
>  ?节点询问的查询将在 manager DB 频繁发生
______________________________________________________________

这里就应该容易理解了,就是把分区信息放到数据表(manager base),
再根据内容key去manager的数据表检索,得到应该去哪检索。

______________________________________________________________
>■algorithm base
> ?node_id = (member_id % 2) + 1
> ?优点
>  ?不需要向 manager DB 询问
> ?缺点
>  ?不易管理
>  ?很难平衡
>  ?需要同时运行相同配置的机器
______________________________________________________________

基于算法的分区不需要配置文件或manager base那样需要检索数据,
只要用一种算法,根据一个唯一key算出平均出现的节点值,而得到分区的信息。
但因为在数据的的平均,导致如果部分用户很活跃,负载会不平衡。

______________________________________________________________
>■节点的追加方法
> ?old_node_id = (member_id % 2) + 1
> ?new_node_id = (member_id % 4) + 1
> ?算出write 地址。如果上述的两个计算结果不同,write 就在两个地址进行
> ?追加之前,read 在 old 进行
> ?移行完了后、read 和 write 都在新的节点进行、删除旧的节点中的数据
______________________________________________________________

这里介绍了基于算法方式下,增加DB节点的方法。


______________________________________________________________
>■partitioning 的问题点
> ?为了显示成员的昵称、或community名等,查询 DB的次数会变多
>  ?很小的数据保存到 memcached
______________________________________________________________

分区的问题就是对小数字的检索可能会不方便,
不过用memcached即可解决。