关于海量数据的数据模型

http://my.oschina.net/chenzuoping/blog/37747

sharding恶梦

国内的很多大型的网站应该都有过sharding的经验。sharding貌似是使用mysql的网站进行性能升级的最重要的手段。 weibo.com,youku.com,douban.com,这此网站都是用sharding作为其性能升级的手段。sharding看起来不错,而 且从weibo  youku  douban的用户体验来说sharding确实给发挥了作用。

sharding一般都是通过把一个数据集非常巨大的表,按主键切割成多个数据表,甚至是把一个数据库分割成多个数据库。这样数据的读写压力就分散到了多个表或多台机器上,这样性能自然而然的会提高了。

虽然sharding带来了性能的重大提升,但其带来的问题也十分明显 。程序逻辑会改变,会带来程序编写上的困难。一个表被sharding成多个子表后,程序要确定到哪个子表找数据。当要进行多表连接查询时,这几乎成了一 个不可完成的任务,因为要连接的子表可能会在另一台机器上。解决的办法是编写一个专门的数据访问层,但随着一次又一次的sharding,数据访问层本身 也变得十分复杂。sharding本身也非常的复杂,做sharding操作的时候要考虑很多问题,要保证Sharding后业务需要的数据操作依然能够 完成,不正确的sharding会给系统带来灾难性的后果,因为其复杂性,所以很容易导致意料不到的错误出现。

新思路

mysql在sharding中出现的问题也使得业界寻找新更好解决方案。google和amazon分别给出了他们的解决方案,分别是 bigtable,和dynamo。bigtable和dynamo有很多区别,但其有一个重要的共同点是它们两者都放弃了关系模型,由上面的分析可以看 出关系模型在海量数据的情形下会出现扩展困难的问题。

它们都采用了一种实体(entity)[1]模型,实体可以理解为一组相互关联的属性的集合,或一个可以任意添加属性但却没有方法的对象。实体的作 用在于把紧密相关系的数据连接在一起,同时区隔开不相关联的数据。实体是最小的分割单位,当数据量变大时数据会被分割到不同的机器上,不同的实体可能会被 分割到不同的机器上,但同一个实体的不同属性必须保存在同一个机器上。

例如可以把一个用户a建模成一个实体,而人的名字(name)、年纪(age)、身高(height)、体重(weight)等一系列信息都可以表 示成该实体的属性。如果a写了一篇文章则可以该文章仍然应该表示成该实体的一个属性(article1),因为该文章是a写的,因此article1和a 之间紧密相联,如果它写了第二篇文章则新建一个article2的属性,如果a发布了一张照片,则该照片也要用a的一个属性photo1来表示,第二个照 片则用属性photo2来表示。

这样做的好处在于,所有相关联的数据都捆绑在一了起。当用户数量大到一定程度一个服务无法存储所有数据,或一台服务器无法负载海量的数据请求时,则 可以把实体分散到不同的服务器上。因为实体之间几乎是完全不关联的,所以实体被分散到不同的服务器上不会给程序带来太大的影响。

上面的这个模型的优点在于模型非常简单,非常适合于分布式存储。还可以实现自动的sharding,因为sharding的时候根本不需要考虑实体关的关系,只需要以实体为单位将实体分布到不同的机器上即可。

 

上面这些思考的内容来自于一篇论文life beyond distributed transactions。里面还讲到了消息传递,状态机等问题。非常值得一读。

你可能感兴趣的:(海量数据)