大数据翻页的难点和技巧

今天要讨论一个传统的问题,问题本身比较简单,就是针对大数据,如何优化方案做到性能与成本的平衡。我们经常会遇到一种Key-list类型数据, 如一个用户的好友关系 {“uid”:{1,2,3,4,5}},表示uid包含有5个好友;一条微博下面的评论id列表{“weibo_id”: {comment_id1, comment_id2……}},一个用户发表的微博id列表等。

在list长度较少时候,我们可以直接的使用数据库的翻页功能,如

SELECT * FROM LIST_TABLE LIMIT offset, row_count;

根据经验,在大部分场景下,单个业务的list数据长度99%在1000条以下,在数据规模较小时候,上面的方法非常适合。但剩下的1%的数据可能多达100万条,在数据规模较大的时候,当访问offset较大的数据,上述方法非常低效(可参看Why does MYSQL higher LIMIT offset slow the query down?),但在实现方案的时候不能忽视这些超大数据集的问题,因此要实现一个适合各种变长list的翻页方案,考虑到数据的长尾问题,并没有简单高效的方案。这也体现了常说的80%+的时间在优化20%-的功能。

List数据访问模型常见的有两种方式

1 . 扶梯方式

扶梯方式在导航上通常只提供上一页/下一页这两种模式,部分产品甚至不提供上一页功能,只提供一种“更多/more”的方式,也有下拉自动加载更多的方式,在技术上都可以归纳成扶梯方式。


(图:blogspot的导航条)

(图:很多瀑布流式的产品只提供一个more的导航条)

扶梯方式在技术实现上比较简单及高效,根据当前页最后一条的偏移往后获取一页即可,在MySQL可使用以下方法实现。

SELECT * FROM LIST_TABLE WHERE id > offset_id LIMIT n;

由于where条件中指定了位置,因此算法复杂度是O(log n)

2. 电梯方式

另外一种数据获取方式在产品上体现成精确的翻页方式,如1,2,3……n,同时在导航上也可以由用户输入直达n页。国内大部分产品经理对电梯方式有特殊的喜好,如图

但电梯方式在技术实现上相对成本较高,当使用以下SQL时

SELECT * FROM LIST_TABLE LIMIT offset, row_count;

我们可以使用MySQL explain来分析,从下文可以看到,当offset=10000时候,实际上MySQL也扫描了10000行记录。

为什么会这样?在MySQL中,索引通常是b-tree方式(但存储引擎如InnoDB实际是b+tree),如图

从图中可以看到,使用电梯方式时候,当用户指定翻到第n页时候,并没有直接方法寻址到该位置,而是需要从第一楼逐个count,scan到 countpage时候,获取数据才真正开始,所以导致效率不高。对应的算法复杂度是O(n),n指offset,也就是pagecount。

另外Offset并不能有效的缓存,这是由于

1、在数据存在新增及删除的情况下,只要有一条变化,原先的楼层可能会全部发生变化。在一个用户并发访问的场景,频繁变化的场景比较常见。

2、电梯使用比较离散,可能一个20万条的list,用户使用了一次电梯直达100楼之后就走了,这样即使缓存100楼之下全部数据也不能得到有效利用。

以上描述的场景属于单机版本,在数据规模较大时候,互联网系统通常使用分库的方式来保存,实现方法更为复杂。

在面向用户的产品中,数据分片通常会将同一用户的数据存在相同的分区,以便更有效率的获取当前用户的数据。如下图所示

(图:数据按用户uid进行hash拆分)

图中的不同年份的数据的格子是逻辑概念,实际上同一用户的数据是保存在一张表中。因此方案在常见的使用场景中存在很大不足,大部分产品用户只访问最 近产生的数据,历史的数据只有极小的概率被访问到,因此同一个区域内部的数据访问是非常不均匀,如图中2014年生成的属于热数据,2012年以前的属于 冷数据,只有极低的概率被访问到。但为了承担红色部分的访问,数据库通常需要高速昂贵的设备如SSD,因此上面方案所有的数据都需要存在SSD设备中,即 使这些数据已经不被访问。

简单的解决方案是按时间远近将数据进行进一步分区,如图。

注意在上图中使用时间方式sharding之后,在一个时间分区内,也需要用前一种方案将数据进行sharding,因为一个时间片区通常也无法用一台服务器容纳。

上面的方案较好的解决了具体场景对于key list访问性能及成本的平衡,但是它存在以下不足

  • 数据按时间进行滚动无法全自动,需要较多人为介入或干预
  • 数据时间维度需要根据访问数据及模型进行精巧的设计,如果希望实现一个公用的key-list服务来存储所有业务的数据,这个公用服务可能很难实现
  • 为了实现电梯直达功能,需要增加额外的二级索引,比如2013年某用户总共有多少条记录

由于以上问题,尤其是二级索引的引入,显然它不是理想中的key list实现,后文继续介绍适合大数据翻页key list设计的一些思路及尝试。

文章转载自 开源中国社区 [http://www.oschina.net]

时间: 2024-09-10 21:57:57

大数据翻页的难点和技巧的相关文章

上海市儿童医院院长:医疗大数据的价值、难点和我们做了什么?

雷锋网(公众号:雷锋网)消息,近日,由HC3i中国数字医疗网.中关村移动互联网产业联盟移动医疗专委会主办的<2017中美智能医疗大数据峰会>在北京召开,上海市儿童医院院长于广军出席并发表演讲. 他认为,大数据不仅能助于科研,还可以为服务模式和管理模式的转变提供支撑.会上,他分享了上海市利用医疗大数据技术改革医疗管理的实践. 医疗大数据的价值和难点 于广军院长称,医疗大数据的发展与医疗信息化紧密相关.医疗信息化经历3个阶段,由财务结算信息化.临床为中心单点信息化到以区域为中心的信息化."

开源大数据平台实施的难点

开源大数据技术是一种新一代技术和构架,它以成本较低.以快速的采集.处理和分析技术,从各种超大规模的数据中提取价值.大数据技术不断涌现和发展,让我们处理海量数据更加容易.更加便宜和迅速,成为分析和挖掘海量数据价值的一个利器,甚至可以改变许多行业的商业模式. 庞大的开源大数据技术体系,使得大数据平台在实施和使用的过程中遇到很多难点,Think Big团队总结了在开源大数据平台设施的整个过程及花费的时间,如下图所示: 1大数据平台的优化和运维 大数据平台的优化和运维应该是开源大数据平台实施的难点.也是

php中文本数据翻页(留言本翻页)

翻页|数据|中文 在mysq中介绍翻页的文章不少,而文本数据表格式的翻页介绍的很少,这里我就简单的说一下翻页 主要介绍以下翻页思想1.留言本的翻页2.文本论坛的翻页 ------------------------留言本的翻页:------------------------------这个在文本数据表中的翻页是最简单的翻页,这样说明一下 golbal file    Data.dat    ---    NOTE FILE USE    user.dat    ---     Forum Fi

php中文本数据翻页(留言本翻页)_php基础

在mysq中介绍翻页的文章不少,而文本数据表格式的翻页介绍的很少,这里我就简单的说一下翻页 主要介绍以下翻页思想1.留言本的翻页2.文本论坛的翻页 ------------------------留言本的翻页:------------------------------这个在文本数据表中的翻页是最简单的翻页,这样说明一下 golbal file    Data.dat    ---    NOTE FILE USE    user.dat    ---     Forum File useDat

Js实现网页键盘控制翻页的方法_javascript技巧

本文实例讲述了Js实现网页键盘控制翻页的方法.分享给大家供大家参考.具体实现方法如下: 键盘控制翻页效果我想我们不少见了,经常在很多网站特别是相册的效果都可以直接使用键盘进行上下页进行翻页了,原理很简单,只要利用js监测用户是否有按上下键即可实现. 举例如下: 复制代码 代码如下: <a id="last" href="<?=$lefturl?>">上一章</a> <a id="booklist" hre

ASP项目中的公共翻页模块_应用技巧

在大型的ASP项目中,很多的页面都涉及到翻页功能.如果每个页面都写一个翻页的程序的话,这样的工作即降低了工作效率,也不利于工程的模块化,不能使代码重用.因此,把翻页这样的功能模块化是很有必要的.   设计方法:  1.调用该模块时,只需要传递记录集和每页显示的记录的条数:  2.可以点击链接进行翻页,也可以直接输入页码,回车后翻页:  3.不要考虑文件名,程序的每次翻页都能在当前页面.  想清楚了上面3个问题,我们的公共翻页模块就可以动手了.  <%  '++++++++++++++++++++

PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部_php技巧

复制代码 代码如下: <?php function ff_page($content,$page) { global $expert_id; $PageLength = 2000; //每页字数 $CLength = strlen($content); $PageCount = floor(($CLength / $PageLength)) + 1; //计算页数 $PageArray=array(); $Seperator = array("\n","\r"

js 拖拽翻页实现代码_javascript技巧

2009-4-9 12:35东方之珠 2009-4-9 12:35啊!停不住的爱人 2009-4-9 12:35宁静温泉 2009-4-9 12:35你的样子 2009-4-9 12:35恋曲1980 2009-4-9 12:35恋曲1990 2009-4-9 12:35恋曲2000 2009-4-9 12:35亚细亚的孤儿 2009-4-9 12:35伴侣 2009-4-9 12:35童年 2009-4-9 12:35爱的箴言 2009-4-9 12:35爱人同志 2009-4-9 12:35

大数据时代已来临,分析成难点

截止到2011年底,全球网民数达22.67亿:截止到2012年6月,中国网民达5.38亿.庞大的网民每时每刻产生大量的数据,据统计:每一分钟全球电子邮件用户共计发出2.04亿封电子邮件:谷歌会处理200万次搜索:Facebook用户会共享68.4万比特的内容--同时,目前用户在网上不仅仅是资讯,同时用户发微博.上传照片.上传视频等,导致数据类型呈现多样性.用户所产生的数据量还将呈现出爆炸式的增长态势,大数据时代已经来临.    在用户的数据量在成几何级数增长的同时,无可否认海量用户数据将会创造出