1.传统数据库改造
提升读性能=增加可读从库(可能会有主从延迟)
提升写能力=横向拆分(业务拆分)+垂直拆分(分库分表)
2.NoSQL基本概念
传统数据库在扩展性上很弱
NoSQL具有扩展性强,优秀的读写性能,天生分布式能力
NoSQL类型
| redis,levelDB | HBASE、Cassandra | MongoDB、CouchDB | |
|---|---|---|---|
| 存储方式 | KV 存储 | 列式存储数据库 | 文档型数据库 |
| 特点 | 极高的读写性能 | 以列来存储数据 | Schema Free(模式自由),数据表中的字段可以任意扩展 |
| 场景 | 性能有高要求 | 你想数据统计场景 | 对字段频繁删减 |
NoSQL的优势
- 弥补传统数据库性能不足
- 数据库变更,不需要改变数据结构
- 适合互联网项目常见的大数据量
SQL的优势
- 强大的查询功能
- 传统数据事务
- 灵活的索引
3.NoSQL写入性能
传统数据系统使用机械磁盘:随机IO(花费时间做昂贵的磁盘寻道)+顺序IO(比随机IO性能提升两到三个数量级)
以MySQL为例:
更新 binlog、redolog、undolog 都是在做顺序 IO(会在内存中保存buffer,达到条件后flush到磁盘)
更新 datafile 和索引文件则是在做随机 IO(页分裂,造成数据移动,极大损耗了写入性能)
NoSQL数据库:以LSM(Log-Structured Merge Tree)树为例
特点:牺牲一定的读性能换取写入数据的高性能
写入实现:
- 数据写入MemTable内存结构中,并且根据key排序(write ahead log方式备份在磁盘上)
- MemTable 在累积到一定规模时,转化成SSTable(Sorted String Table)
- SSTable也会进行合并(有序的情况下合并很快)
读取实现:
- 首先从MemTable 中查找数据
- 如果数据没有找到,再从 SSTable 中查找数据
- 存储的数据都是有序的,所以查找的效率是很高的(二分查找),只是因为数据被拆分成多个 SSTable,所以读取的效率会低于 B+ 树索引
NoSQL的倒排索引
解决了SQL的模糊查询有些情况下不能命中索引的情况
什么是倒排索引:
对记录进行分词,反向存储记录ID
Elasticsearch 作为一种常见的 NoSQL 数据库,就以倒排索引作为核心技术原理,为你提供了分布式的全文搜索服务,这在传统的关系型数据库中使用 SQL 语句是很难实现的。
传统数据库:
倒排索引
4.NoSQL的扩展性
MongoDB 就有三个扩展性方面的特性
- Replica副本集
- 主从分离,主写重读
- 主的写入oplog(类似binlog)发送给从节点,并保证主从一致
- 主节点挂掉后,可以选取从节点继续服务
- Shard分片
- 分库分表
- 三个角色
- Shard Server 实际存储数据的节点,独立的 Mongod 进程
- Config Server,也是一组 Mongod 进程,主要存储一些元信息(在那些分片存储了那些数据)
- 最后是 Route Server,它不实际存储数据,仅仅作为路由使用
- 负载均衡
- MongoDB 发现 Shard 之间数据分布不均匀,会启动 Balancer 进程对数据做重新的分配,最终让不同 Shard Server 的数据可以尽量的均衡。
- 减少了运维人员数据迁移和验证的成本
NoSQL 数据库中内置的扩展性方面的特性可以让我们不再需要对数据库做分库分表和主从分离,也是对传统数据库一个良好的补充。
NoSQL 只能作为传统关系型数据库的补充而存在,弥补关系型数据库在性能、扩展性和某些场景下的不足
5.总结
NoSQL的优势与特点
- 将SQL的磁盘随机写转换成顺序写,提升了写性能
- 支持SQL覆盖不到的场景,例如全文搜索功能
- 天生支持分布式,支持数据冗余和数据分片的特性
NoSQL 可供选型的种类很多,每一个组件都有各自的特点。你在做选型的时候需要对它的实现原理有比较深入的了解,最好在运维方面对它有一定的熟悉,这样在出现问题时才能及时找到解决方案。
所以,对于开源组件的使用,不能只停留在只会“hello world”的阶段,而应该对它有足够的运维上的把控能力。