对于访问压力较高的网站,如淘宝、校园网、开心网等,都会面对海量用户的并发访问情景,如何有效的存储数据,为用户提供快速的访问体验,同时还需要具备良好的扩容能力,成为数据存储方案选择的关键。例如SNS网站的人人网,据称其PV(Page View,页面浏览量,或称点击量)访问量为亿级。
如此大规模的访问量,传统的将数据存储于一个数据库的集中式存储方式,很难提供良好的数据层支持。
根据分而治之的思想,可以对数据库进行纵向或横向的拆分,即Database Sharding。
根据拆分的不同方法,可以分为纵向拆分和横向拆分。
纵向拆分:即根据不同的应用,分别设置不同数据应用数据库,如视频类数据、图片类数据、新闻数据等;其特点是面对不同的应用,其数据表结构有所不同。
横向拆分:就是设置同等结构的多个数据库(称作数据节点,Node),其特点是各节点具有同等的数据表结构,只是针对不同的用户群,如用户一的数据存储在节点一上,用户二的数据存储于数据节点二上,等等。
由于纵向拆分随着存储规模的不断扩大,也同样会遇到扩容压力的影响,其扩张能力相对横向拆分更复杂些,所以采用横向拆分的方案比较多见。
横向拆分几种常见的方法:
1、散列法
如根据用户的ID号,经过散列算法,将用户的数据均匀的散列分布在不同的数据库节点上。散列的算法可以按照用户的ID编号,IP地址分布、访问线路(如电信、网通、铁通)等因素进行散列;
优点:根据散列算法,可以将各节点负载分配的比较均衡;
缺点:扩容困难,如果要增加新的数据库节点,需要更新散列算法,同时还要考虑对原始数据依据新散列算法的迁移工作,增加了不稳定性。
2、全局节点数据表法
就是将用户的数据所在的节点信息存放在一个全局数据库表中,类似与用户数据的“门牌号”,用户访问数据时,首先查看用户数据所在的节点信息,然后到该节点去获取数据。分配节点的算法可以按照每个节点的存储容量、每个节点的分配概率(如访问量大的节点其概率低)等。
优点:扩容方便,扩容时只需要增加节点,还有在全局数据表中增加其“门牌号”即可。
缺点:由于所有的数据都需要访问全局数据库表,容易造成访问的瓶颈。
更多的思考:
1、以上的存储都是基于物理的存储和拆分,而系统在运行时,由于用户访问的不确定性,如何保证各数据库节点运行压力的均衡分布?
2、如果要保证运行时各节点压力的均衡分布,如何保证其物理存储的相对稳定?
3、如何有效的对拆分数据进行全局的查找和统计?