NoSQL架构实践(一)——以NoSQL为辅
前面《为什么要使用NoSQL》和《关系数据库还是NoSQL数据库》两篇从大体上介绍了为什么要用NoSQL,何时该用NoSQL。经常有朋友遇到困惑,看到NoSQL的介绍,觉得很好,但是却不知道如何正式用到自己的项目中。很大的原因就是思维固定在MySQL中了,他们问得最多的问题就是用了NoSQL,我如何做关系查询。那么接下来,我们看下怎么样在我们的系统中使用NoSQL。
怎么样把NoSQL引入到我们的系统架构设计中,需要根据我们系统的业务场景来分析,什么样类型的数据适合存储在NoSQL数据库中,什么样类型的数据必须使用关系数据库存储。明确引入的NoSQL数据库带给系统的作用,它能解决什么问题,以及可能带来的新的问题。下面我们分析几种常见的NoSQL架构。
(一)NoSQL作为镜像
不改变原有的以MySQL作为存储的架构,使用NoSQL作为辅助镜像存储,用NoSQL的优势辅助提升性能。
图 1 -NoSQL为镜像(代码完成模式 )
//写入数据的示例伪代码 //data为我们要存储的数据对象
data.title=”title”;
data.name=”name”;
data.time=”2009-12-01 10:10:01”;
data.from=”1”;
id=DB.Insert(data);//写入MySQL数据库
NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库
如果有数据一致性要求,可以像如下的方式使用
//写入数据的示例伪代码
//data为我们要存储的数据对象
bool status=false;
DB.startTransaction();//开始事务
id=DB.Insert(data);//写入MySQL数据库
if(id>0){
status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库
}
if(id>0 && status==true){
DB.commit();//提交事务
}else{
DB.rollback();//不成功,进行回滚
}
上面的代码看起来可能觉得有点麻烦,但是只需要在DB类或者ORM层做一个统一的封装,就能实现重用了,其他代码都不用做任何的修改。
这种架构在原有基于MySQL数据库的架构上增加了一层辅助的NoSQL存储,代码量不大,技术难度小,却在可扩展性和性能上起到了非常大的作用。只需要程序在写入MySQL数据库后,同时写入到NoSQL数据库,让MySQL和NoSQL拥有相同的镜像数据,在某些可以根据主键查询的地方,使用高效的NoSQL数据库查询,这样就节省了MySQL的查询,用NoSQL的高性能来抵挡这些查询。
图 2 -NoSQL为镜像(同步模式)
这种不通过程序代码,而是通过MySQL把数据同步到NoSQL中,这种模式是上面一种的变体,是一种对写入透明但是具有更高技术难度一种模式。这种模式适用于现有的比较复杂的老系统,通过修改代码不易实现,可能引起新的问题。同时也适用于需要把数据同步到多种类型的存储中。
MySQL到NoSQL同步的实现可以使用MySQL UDF函数,MySQL binlog的解析来实现。可以利用现有的开源项目来实现,比如:
- MySQL memcached UDFs:从通过UDF操作Memcached协议。
- 国内张宴开源的mysql-udf-http:通过UDF操作http协议。
有了这两个MySQL UDF函数库,我们就能通过MySQL透明的处理Memcached或者Http协议,这样只要有兼容Memcached或者Http协议的NoSQL数据库,那么我们就能通过MySQL去操作以进行同步数据。再结合lib_mysqludf_json,通过UDF和MySQL触发器功能的结合,就可以实现数据的自动同步。
(二)MySQL和NoSQL组合
MySQL中只存储需要查询的小字段,NoSQL存储所有数据。
图 3 -MySQL和NoSQL组合
//写入数据的示例伪代码 //data为我们要存储的数据对象
data.title=”title”;
data.name=”name”;
data.time=”2009-12-01 10:10:01”;
data.from=”1”;
bool status=false;
DB.startTransaction();//开始事务
id=DB.Insert(“INSERT INTO table (from) VALUES(data.from)”);//写入MySQL数据库,只写from需要where查询的字段
if(id>0){
status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库
}
if(id>0 && status==true){
DB.commit();//提交事务
}else{
DB.rollback();//不成功,进行回滚
}
把需要查询的字段,一般都是数字,时间等类型的小字段存储于MySQL中,根据查询建立相应的索引,其他不需要的字段,包括大文本字段都存储在NoSQL中。在查询的时候,我们先从MySQL中查询出数据的主键,然后从NoSQL中直接取出对应的数据即可。
这种架构模式把MySQL和NoSQL的作用进行了融合,各司其职,让MySQL专门负责处理擅长的关系存储,NoSQL作为数据的存储。它有以下优点:
- 节省MySQL的IO开销。由于MySQL只存储需要查询的小字段,不再负责存储大文本字段,这样就可以节省MySQL存储的空间开销,从而节省MySQL的磁盘IO。我们曾经通过这种优化,把MySQL一个40G的表缩减到几百M。
- 提高MySQl Query Cache缓存命中率。我们知道query cache缓存失效是表级的,在MySQL表一旦被更新就会失效,经过这种字段的分离,更新的字段如果不是存储在MySQL中,那么对query cache就没有任何影响。而NoSQL的Cache往往都是行级别的,只对更新的记录的缓存失效。
- 提升MySQL主从同步效率。由于MySQL存储空间的减小,同步的数据记录也减小了,而部分数据的更新落在NoSQL而不是MySQL,这样也减少了MySQL数据需要同步的次数。
- 提高MySQL数据备份和恢复的速度。由于MySQL数据库存储的数据的减小,很容易看到数据备份和恢复的速度也将极大的提高。
- 比以前更容易扩展。NoSQL天生就容易扩展。经过这种优化,MySQL性能也得到提高。
比如手机凤凰网就是这种架构 http://www.cnblogs.com/sunli/archive/2010/12/20/imcp.html
总结
以NoSQL为辅的架构还是以MySQL架构的思想为中心,只是在以前的架构上辅助增加了NoSQL来提高其性能和可扩展性。这种架构实现起来比较容易,却能取得不错的效果。如果正想在项目中引入NoSQL,或者你的以MySQL架构的系统目前正出现相关的瓶颈,希望本文可以为你带来帮助。
感谢张凯峰对本文的审校。
from :http://www.infoq.com/cn/news/2011/02/nosql-architecture-practice/
NoSQL架构实践(一)——以NoSQL为辅的更多相关文章
- NoSQL架构实践
经常有朋友遇到困惑,看到NoSQL的介绍,觉得很好,但是却不知道如何正式用到自己的项目中.很大的原因就是思维固定在MySQL中了,他们问得最多的问题就是用了NoSQL,我如何做关系查询.那么接下来,我 ...
- 大数据架构师必读的NoSQL建模技术
大数据架构师必读的NoSQL建模技术 从数据建模的角度对NoSQL家族系统做了比较简单的比较,并简要介绍几种常见建模技术. 1.前言 为了适应大数据应用场景的要求,Hadoop以及NoSQL等与传统企 ...
- 基于 Docker 的微服务架构实践
本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...
- 朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招
朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招 概览 标题中的高并发架构设计是指设计一套比较合适的架构来应对请求.并发量很大的系统,使系统的稳定性.响应时间符合预期并且能在极端的情况下自 ...
- NoSQL开篇——为什么要使用NoSQL
NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面.今年伊始,InfoQ中文站有幸邀请到凤凰网的孙立先生,为大家分享他之于N ...
- Windows平台分布式架构实践 - 负载均衡(下)
概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...
- 大型网站系统架构实践(五)深入探讨web应用高可用方案
从上篇文章到这篇文章,中间用了一段时间准备,主要是想把东西讲透,同时希望大家给与一些批评和建议,这样我才能有所进步,也希望喜欢我文章的朋友,给个赞,这样我才能更有激情,呵呵. 由于本篇要写的内容有点多 ...
- 大型网站系统架构实践(六)深入探讨web应用集群Session保持
原理 在第三,四篇文章中讲到了会话保持的问题,而且还遗留了一个问题,就是会话保持存在单点故障, 当时的方案是cookie插入后缀,即haproxy指负责分发请求,应用服务自行保持用户会话,如果应 用服 ...
- Windows平台分布式架构实践负载均衡
Windows平台分布式架构实践 - 负载均衡 概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Li ...
随机推荐
- 测试in和or的执行时间
declare @d datetime set @d=getdate() /*你的SQL脚本开始*/ SELECT * FROM T_KNOWLEDGE WHERE KNOWLEDGE_TYPE_OI ...
- Java-在线聊天系统-线程
一.概述 1.目标:在上一个版本非线程的聊天系统中,出于要不断监听接收新client和接收client发出的信息,把accept()和DataInputStream.readUTF()分别写在了whi ...
- SendTextMessage如何打开记事本并显示指定内容
procedure TForm1.Button1Click(Sender: TObject); var hEdit: HWND; str: string; begin str := '准备要添加到记事 ...
- Android:开发环境
一.JAVA SDK(JDK)的安装 http://www.cnblogs.com/tinyphp/p/3664598.html 二.ADT-Bundle 包含了Eclipse.ADT插件和SDK T ...
- 【查找结构4】红黑树 [RBT]
红黑树的性质与定义 红黑树(red-black tree) 是一棵满足下述性质的二叉查找树: 1. 每一个结点要么是红色,要么是黑色. 2. 根结点是黑色的. 3. 所有叶子结点都是黑色的(实际上都是 ...
- java异常——RuntimeException和User Define Exception
1.RuntimeException public class RuntimeException { public static void main(String[] args) { // TODO ...
- Zn离子参数
Generating Topology and Coordinates Files Using xLeap (AmberTools V1.5) Parameter and example files: ...
- python 中的map 详解
python中的map函数应用于每一个可迭代的项,返回的是一个结果list.如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理.map()函数接收两个参数,一个是函 ...
- CVS数据的导入和导出
2.CSV导入/导出测试 package junit.test; import java.io.File; import java.util.ArrayList; import java.util.L ...
- dotnet il editor 调试 iis 程序
没有C#源代码,IL级别调试.听说windbg也可以,不过windbg有些难.另外il其实一般写C#程序也不熟,不过我目的只是找出异常点,到客户一般不发pdb文件,出去也是release版本,出异常( ...