多对多关系以及多表查询优化处理
上篇以用户数据表为例介绍了基本的数据分割方案以及基本的配置方案。但是在2.0时代,这种简单的列表索引已经远远实现起来是问题的,多对多关系将是最常见的关系。现在我们针对web2.0数据中广泛存在的多对多关系进行阐述和具体行为判断,比如一个很简单的例子,在2.0时代,好友功能是最常被用到的,每个用户会有很多的好友,同时也会是很多人的好友,那么这个数据量将会是用户数的平方的级别。同样,对于文章标签,每个文章可以有多个标签,而每个标签又可以有多个文章,这又是一个几何乘积,数据量又会是个天文数字。这里不再介绍基于硬件,IO,集群方面的问题,我们以项目开发的角度来实现他
这里先介绍一个基本的施行方案,而后我们进一步的对它进行扩充以满足我们的以后的具体需求
对于多对多关系,传统的处理方案有三种,一种是通过SEARCH的方法来实现,第二一种是通过另建一个索引表,存贮对应的ID以进行存贮,第三种是通过二次归档缓冲来实现(本人不知道用什么语言来描述这种处理方法,姑且如此吧)
对于第一种方案,因为要涉及大量的LIKE查询,性能不敢恭维,基于全文索引的方式可能解决这个问题,但是利用第三方的数据可能未必能适合我们的胃口,我们也可能没有足够的时间和精力来独立开发实现。第二种的情况下,数据库的行的数量也是惊人海量级别的,维护索引表的散列处理,并且要跨表跨区查询,还要维护数据的唯一性,数据处理过程相 当的复杂性能也就不言而喻了。
文入正题,下面以一个简单的例子解释下第三种方案,对数据多对多关系举出来具体的解决方案,我们这里以标签和文章之间的多对多关系为例来讲解,大家可以举一反三的思考群组和用户之间,相册和被圈用户之间等等复杂的多对多关系,如下方案可能不是最好的方案,但是实践证明还是综合时间和开发成本是最合理的。
首先滤清一下流程,在传统的数据库设计中我们是如下走的:当一篇博文发布的时候并插入标签的时候一般是三步走(也可以理解为四步,以为还要判断标签是否存在的问题),第一步插入文章数据库并获取文章的ID,第二步插入标签数据库同时查询标签是否存在,如果存在就取出标签的ID,否则的话插入新标签并取出ID,第三部,将文章的ID和标签的ID插入索引表来建立关联。如果这个时候在索引表上建立了索引的话就是灾难性的,特别是在数据量大的情况下,尽管它可以有效的提高查询速度,但是发布的速度可能就会让人无法忍受了。
我们处理的方法也是四部曲,对多对多关系进行进一步的处理。
用标签的时候,我们用的最多的就是查询标签下的文章和显示文章的标签,所以我们实现这例就成了。
第一步,数据冗余
老生常谈的话题,对文章做冗余,加一个TAG列,我们可以讲TAG的标签如下写[TagID,TagName]| [TagID,TagName]| [TagID,TagName] 同样对于TAG表,我们做如下冗余加个Article字段,如下内容[ArticleID,Title]| [ArticleID, Title]| [ArticleID, Title],在需要增加的时候我们只要APPEND一下就可以了,至于ARTICLE的结构和TAG的结构可以参考我上一篇文章的介绍。其实根据需要还可以存贮更多。
有人会问,为什么要存贮TagName和 ArticleTitle呢,其实是为了避免跨表查询和INNERJOIN查询来做的,In查询和跨表查询会造成全表遍历,所以我们在执行的时候In查询是必须要找到一个有效的替代方法的。关于数据冗余的问题,我们可能还会做的更变态一些,这个后面慢慢说。
第二步:异步存贮。
在设计模式下我们常思考的是单件模式,我们采用另类的单件模式思维来处理,也就是把文章和标签之间的索引作为专门的进程来做,异步的实现。
为了避免文章在发布的时候以为要检查TAG表而造成的线程拥堵,我们需要采取延迟加载的方案来做。服务器应该维护一个进程专业的对标签和文章地段的查询和索引,我们在发布文章的时候应该把标签同步这一块托管给另外的一个进程或者服务器进行处理,并进行索引。
第三步:二次索引:
对于频繁的判断标签去或者热门的标签我们还可以在内存里组织一套有效的索引,比如对于标签“疯狂代码”,我们用树来把它表示出来。对于疯狂代码我们索引一个疯,其实用程序表达就是疯狂代码[0]。而在数组”疯”中存贮以疯开头的标签组,以”傲”的数组中存贮以”傲”开头的标签。如果量更大的话还可以再做N级索引,将这些常用的标签对应设计内存索引,我们可以把它想象的理解为内存中的 Suggest(比如google搜索时的Suggest),使用中我们可以直接拿来使用
第四步:针对跨表查询的处理
很多情况下,我们可能避免不了多表查询,或者 IN,or查询,除去业务层封装的分区视图集群之外,我们还可以处理的更好,在很多情况下,我们的查询会是非常频繁非常统一的(这里的统一指热门查询),比如在SNS中常见的性别,嗜好等多条件搜索,而这些数据可能存贮在多个数据表结构中,而这样会吧不可避免的会产生全表遍历查询。
处理方法也很简单,把原来散列的垂直分割的表再合并起来,合并到另外的只读的订阅服务器上,然后做适当的结构优化和索引,剩下的大家应该明白我的意思了,虽然简单,但是这种处理方法非常适合以后服务器的横向扩充。
以上是对多对多关系和多表查询的一个简单的架构说明,肯定有人会问,如果这样做的话工作量不是太大了吗,分词处理什么的,对每个多对多关系进行处理。
OK,咱们可以进一步的把它来抽象化,我们用TableA 表示Article表,用TagbleT表示Tag表,我们可以讲字段抽象化出来,也就是一个ID,一个Tag的String 同理对于标签表也是如此。朋友们应该可以理解我的意思了。
对,就是做个代码生成器把对应的多对多关系给生成出来,这个很好写的,几个Append就可以搞定。如果想更方便的处理,那么把这个东西做成单件的模式抽象化出来,然后再违反一下原则,做成基类,其他关系继承这个基类。。。。。剩下的应该很简单了,具体实现大家思考吧。
让并发来的更猛烈些吧,高并发环境下的数据处理方案
对于高并发性质的网站,在sns特别是webgame方面应该是最容易也是最难处理的地方了,容易处理的是如果是纯粹基于数据库驱动也就是 select和update的问题,而难的地方也是不是select而是update,在高并发的驱动下,update经常会超时,虽然我们可以在 finally把它处理掉,让人郁闷的是,数据库连接池仍然会饱和,数据仍然会丢失….
上面的情况是非常常见的web项目失败的原因之一,在数据飞速膨胀和并发呈几何级增长的情况下,制约我们的可能是io,database本身的问题了,让我们头痛的是不管是哪种数据库,Oracle也好,mysql也好,sqlserver也好都会timeout,而且是频繁的timeout频繁的Exception。这个时候就需要我们的应用程序在处理的前期就应该考虑到的,一个好的数据缓存策略常常决定了我们的成败,而缓存策略也是web项目最难以测试和最容易出错的地方。
在大型网站架构中,最关键最核心的也是缓存策略了,介于其复杂性,这里只简单的介绍一下基于高并发数据库缓存方案,后面的将详细介绍常用的缓存策略。这个方法与其叫缓存不如叫数据缓冲,其实也是异步更新数据,根据负载情况不同,我们哪怕仅仅将数据缓冲1秒,带来的负载提升就已经非常好了。
实现原理很简单,将并发的更新首先缓存到一个应用程序池中,然后定时查询(注意这里的方案应和缓存方案具体结合,这里只介绍概要情况)。
传统的update请求处理流程是:请求—》应用程序—》更新数据库,如下图:
数据缓冲和更新部分可以在数据层里独立实现,也就是update的传递的时候首先传递缓冲池,然后定时更新,这里需要注意的数据缓冲池的还要做的另外一份工作就是全局的数据缓存,缓存数据更新到数据这段的时间间隔,我们可以理解为临时表,再提取上下文请求的即时信息的时候首先从缓冲池里读取(这里有很多技巧,比如巧妙的利用cookie,session做;临界条件判断),流程如下图所示
上面简单的介绍了一下基于数据更新缓存的处理,下篇具体详细介绍基于并发更新机制的详细缓存处理机制
发表评论
-
Freemarker模板应用
2012-07-23 22:38 3116FreeMarker是一个模板引擎,一个基于模板生成 ... -
freemarket学习日志(持续更新)
2012-07-03 17:34 1520实际工作中有用到就现学就卖哈 freemarker ... -
freemarker常见语法大全
2012-06-25 10:33 2597转自:http://yangq.iteye.com/ ... -
Eclipse常用插件(持续更新中)更新地址
2012-05-21 08:31 913SVN Client http://subclipse ... -
验证码识别技术研究
2012-05-09 10:09 2630转载自:http://hi.baidu.com/mrcaptc ... -
Project Lombok—方便实用的annotation工具
2012-05-08 18:13 3595Project Lombok 项目地址:http://proj ... -
用Lombok减少重复代码,很美很简单
2012-05-08 17:56 1120无意中看到这样一个小框架,看完之后,真是不得不顶,很简单 ... -
一步步构建大型网站架构
2012-04-17 08:27 909转自:http://kb.cnblogs.com/pag ... -
大型网站系统架构分析
2012-04-16 11:01 1408最近在讨论研究框架,准备框架的编写和资料。 文章转自:htt ... -
领域模型的概念:失血 贫血 充血 胀血
2012-04-10 10:10 2573转自:http://blog.csdn.net/s ... -
大型网站架构系列之五,缓存策略设计概要
2012-03-25 11:20 1576上篇对疯狂代码缓存配置进行了概要的设计,可能说的有点模糊了,有 ... -
大型网站架构系列之三,多对多关系的优化设计
2012-03-24 12:07 1217上篇以用户数据表为例介绍了基本的数据分割方案以及基本的配置 ... -
大型网站架构系列之二,底层架构概论
2012-03-24 12:06 1010首先澄清上篇中关于几个朋友的评论。 上篇疯狂代码介绍的基 ... -
大型网站架构系列之一,前言,不得不考虑的问题
2012-03-24 12:02 868前言:这两天机器坏 ...
相关推荐
对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表...
亿级流量电商详情页系统的大型高并发与高可用缓存架构是如何设计与实现的
期望通过本套课程能帮助大家学习到一些高阶的技术,复杂问题的解决方案,以及应对挑战性场景的大型架构设计思想。熟练掌握亿级流量电商网站的商品详情页架构如何设计与实现,能够应对各种复杂场景与挑战问题的缓存...
不再只是关注电商详情页架构中的缓存架构部分,而是关注全链路、全流程的完整架构,对完整的架构进行设计以及开发,包括了动态渲染系统、OneService系统、前端页面、大型工程运维四个部分。 2、基于更加完整的业务...
包含ELK、Haproxy、Nginx、Tomcat、Ansible自动化运维实战、缓存、架构设计等等
亿级流量电商详情页系统的大型高并发与高可用缓存架构实战-未加密
完整的大型电商详情页系统架构:不再只是关注电商详情页架构中的缓存架构部分,而是关注全链路、全流程的完整架构,对完整的架构进行设计以及开发,包括了动态渲染系统、OneService系统、前端页面、大型工程运维四个...
大型高并发网站的性能除了受硬件设施影响外,高性能的软件技术应用和高度优化的 系统架构的作用也格外重要。文章首先讨论外网中在全国范围使用的镜像网站,CDN 内容分 发网络等加速技术,其次着重对本地服务器内网中...
大型分布式网站架构设计与实践+笔记.zip 1.Cache缓存 2.持久化存储 3.消息系统MQ 4.垂直化搜索引擎 5.其他基础设施
大型分布式网站架构:基础设施-缓存+NoSQL,Web高并发及解决方案等等
搭建高性能大并发大型网站架构 教程.zip 1.服务器操作系统用64位的CentOS 2.mysql数据库 3.nosql redis缓存 4.web网站代码 5.nginx 6.apache php 7.tomcat java 8.squid前台静态资源缓存 9.CDN服务器 10.固态硬盘+...
本文围绕高并发高流量的网站架构设计问题,主要研究讨论了以下内容: 首先在整个网络的高度讨论了使用镜像网站,CDN内容分发网络等技术对负载均衡带来的便利及各自的优缺点比较。然后在局域网层次对第四层交换技术...
主要是基于简化以后的大型电商详情页系统的背景,来重点讲解了三块内容: Redis集群架构、大型 高并发缓存架构以及基于Hystrix的高可用服务架构。而本次的《亿级流量电商详情页系统实战(第二版):缓存架构+高可用...
亿级流量电商详情页系统的大型高并发与高可用缓存架构实战-未加密版本有时间可以学习一下,挺不错的一个资源!(对高并发,高可用缓存等详细介绍)
解决方案:基于随机过期时间的缓存失效解决方案课程大纲:第01节课程介绍以及高并发高可用复杂系统中的缓存架构有哪些东西?第02节基于大型电商网站中的商品详情页系统
大型网站架构演化 大型网站软件系统的特点 大型网站架构演化发展历程 初始阶段 应用服务和数据服务分离 使用缓存改善网站性能 缓存类型 本地缓存 分布式缓存 缓存产品 redis 业界...
搭建一个大型网站架构的实验环境(FreeBSD系统安装篇)(FreeBSD系统设置篇)(FreeBSD系统优化篇)(Nginx代理服务器篇)(Squid缓存服务器篇)(Web服务器篇)(集成篇)(虚拟机篇)
大型网站的架构设计问题 25 开源平台的高并发集群思考 26 大型、高负载网站架构和应用初探 时间:30-45分钟 27 说说大型高并发高负载网站的系统架构 28 mixi技术架构 51 mixi.jp:使用开源软件...