【AICon】探索八个行业创新案例,教你在教育、金融、医疗、法律等领域实践大模型技术! >>> 了解详情
写点什么

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


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

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2011-02-18 23:1119677

评论

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

【团队效率提升】Python-PyWebIO介绍

京东科技开发者

html 软件 markdown Python. 企业号 1 月 PK 榜

前端一面react面试题总结

beifeng1996

React

聚焦技术创新实力,时序数据库 TDengine 荣登中国技术先锋年度评选两大榜单

TDengine

数据库 tdengine 时序数据库

写过vue自定义指令吗,原理是什么?.m

bb_xiaxia1998

Vue

前端经典面试题(有答案)

loveX001

JavaScript

【从零开始学爬虫】采集食品行业最新报价数据

前嗅大数据

数据采集 爬虫软件 爬虫案例 爬虫入门教程 爬虫分享

深航携手华为云,共建数字化智慧民航标杆

Geek_2d6073

Hyperledger AnonCreds:开源、开放规范下,保护隐私的可验证凭证

BSN研习社

架构实战 - 模块 6 作业

mm

#架构实战营 电商微服务分析

跨集群流量调度实现 Kubernetes 集群金丝雀升级

Flomesh

K8s 多集群管理 流量管理

谈谈前端性能优化-面试版

loveX001

JavaScript

在vue的v-for中,key为什么不能用index?

bb_xiaxia1998

Vue

如果才能做好准备好前端面试

loveX001

JavaScript

HummerRisk V0.8.0:新增金山云、K8s基准检测、源IP审计分析等

HummerCloud

Kubernetes 云安全 云原生安全

React组件之间的通信方式总结(下)

beifeng1996

React

美团前端一面必会react面试题

beifeng1996

React

FLStudio水果萝卜最新汉化21版本下载

茶色酒

flstudio FLStudio21 FLStudio21.0.0

Java高手速成 | Spring、JPA与Hibernate的整合

TiAmo

hibernate Spring JPA Spring Java

React组件之间的通信方式总结(上)

beifeng1996

React

SREWorks v1.4 版本发布 | 离线安装 & 前端重构

阿里云大数据AI技术

大数据 开源 运维 企业号 1 月 PK 榜

水印LOGO有哪些类型?如何在线给图片添加水印LOGO?

互联网民工阿强

图片处理 添加水印 水印 水印LOGO

我在京东做研发 | 京东云算法科学家解析爆火的ChatGPT

京东科技开发者

AI 技术 算法 经验分享 ChatGPT

这些js原型及原型链面试题你能做对几道

loveX001

JavaScript

【12.30-1.6】写作社区优秀技术博文回顾

InfoQ写作社区官方

热门活动

火山引擎DataLeap数据调度实例的 DAG 优化方案

字节跳动数据平台

大数据 数据治理 数据研发

FinClip 12 月大事件 | IDE支持小游戏开发调试和预览

FinClip

小游戏引擎如何选?看完这篇就够了

FinClip

Java中不可或缺的关键字「volatile」

小小怪下士

Java 程序员 volatile

字节前端必会vue面试题集锦

bb_xiaxia1998

Vue

2023前端二面必会vue面试题指南

bb_xiaxia1998

Vue

构建自组织团队,让敏捷管理更好地落地

敏捷开发

项目管理 敏捷开发 项目管理软件 自组织

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