写点什么

NoSQL 架构实践(一)——以 NoSQL 为辅

  • 2011-02-18
  • 本文字数:2379 字

    阅读完需:约 8 分钟

前面《为什么要使用 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 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 架构的系统目前正出现相关的瓶颈,希望本文可以为你带来帮助。


感谢张凯峰对本文的审校。

2011-02-18 23:1120377

评论

发布
暂无评论
发现更多内容

如何将物理机Windows系统迁移到VMware虚拟机?

天翼云开发者社区

Knative Autoscaler 自定义弹性伸缩

天翼云开发者社区

广告商、影视剧和晚会用的流行歌曲,版权都是怎么买的?

曲多多(嗨翻屋)版权音乐

音乐 三体 版权 影视 热点

高性能网络SIG月度动态:SMC 与 IBM 就扩展协议达成一致,virtio 支持 XDP 新特性

OpenAnolis小助手

开源 高性能网络 virtio 龙蜥sig smc

架构训练营模块五作业

gigifrog

架构训练营

为什么工厂要投资设备智能维护管理技术?

PreMaint

设备管理 设备预测性维护

大数据培训的方法有哪些

小谷哥

参加大数据培训有什么好处

小谷哥

携手共进丨九科信息入围PKS体系生态企业展播

九科Ninetech

3D可视化:18个WebGL框架和Web3D图形库

2D3D前端可视化开发

WebGL 三维可视化 web3d 3d绘图引擎

关于 OAuth 你又了解哪些?

API7.ai 技术团队

api 网关 Oauth APISIX

基于Prometheus和Grafana实现对SpringBoot 应用的监控

皮特王

监控 Grafana Prometheus 大屏展示 告警平台

线下学习前端培训机构怎么选?

小谷哥

《福布斯》评英特尔最新财报:业绩之外,制程路线图的稳步推进是真正的好消息

科技之家

找 ChatGPT 写 SQL? 不如试试 PromQL,三行解决复杂时序场景查询

Greptime 格睿科技

sql 云原生 时序数据库 PromQL 可观测

腾讯架构师极力推荐:Java多线程与Socket实战微服务框架

小小怪下士

Java 程序员 socket 多线程

Elasticsearch 利用 Enrich Processor 实现 MYSQL Join 的操作,支持 Nested 类型,具体应用。

alexgaoyh

MySQL elasticsearch ES 多表join enrich processor

您有一个MatrixOne Beta Program专属权益待领取

MatrixOrigin

MatrixOrigin MatrixOne betaprogram MO企划

初学者前端培训机构需要注意什么

小谷哥

【SpringBoot】简述springboot项目启动数据加载内存中的三种方法

No8g攻城狮

springboot spring-boot

软件测试/测试开发 | Web测试方法与技术之JavaScript 讲解

测试人

软件测试 自动化测试 测试开发 Web自动化测试 web测试

《解构领域驱动设计》-领域驱动设计统一过程

珑彧

Java 读书笔记 架构 方法论 领域驱动设计

为什么选择免费文件共享方法上的托管文件传输

镭速

RESTful API 为何成为顶流 API 架构风格?

API7.ai 技术团队

API APISIX REST API

《自定义工作流配置,springboot集成activiti,前端vue,完整版审批单据》

金陵老街

如何通过极狐GitLab 平滑落地 Java 增量代码规范?

极狐GitLab

Java DevOps 代码规范 极狐GitLab checkstyle

3Dmax和C4d有什么区别?

Finovy Cloud

3DMAX

文本数据标注已上线,支持文本分类、实体识别|ModelWhale 版本更新

ModelWhale

人工智能 机器学习 云计算 数据分析 编程建模

java培训与线上自学哪个比较好?

小谷哥

NoSQL架构实践(一)——以NoSQL为辅_Java_孙立_InfoQ精选文章