数据库-总结列表
--------------------------------------------
一、基础篇
查询数据
本节将学习如何从Oracle数据库中查询数据。
● Select语句 - 演示如何查询单个表中的数据。
排序数据
● ORDER BY语句 - 按升序或降序对查询的结果集进行排序。
过滤数据
● DISTINCT - 介绍如何消除查询输出中的重复行。
● WHERE - 演示如何为查询返回结果集中的行记录指定过滤条件。
● AND - 组合两个或两个以上的布尔表达式,如果所有表达式都为true,则返回true。
● OR - 组合两个或两个以上的布尔表达式,如果其中一个表达式为true,则返回true。
● FETCH - 演示如何使用行限制子句限制查询返回的行数。
● IN - 确定值是否与列表或子查询中的任何值相匹配。
● BETWEEN - 基于一系列值(区间值)过滤数据。
● LIKE - 根据特定模式执行匹配。
连接表
● INNER JOIN - 演示如何从表中查询具有与其他表匹配的行记录。
● LEFT JOIN - 介绍左连接概念,并学习如何使用它选择左表中具有,但右表中不具有的行记录。
● RIGHT JOIN - 解释右连接概念,并演示如何从右表查询具有,但左表中不具有的行记录。
● CROSS JOIN –介绍如何从多个表中构建笛卡尔乘积。
● Self Join - 演示如何将表连接到自身以查询分层数据或比较同一个表中的行记录。
分组数据
● GROUP BY - 演示如何将行分组为子组,并为每个分组应用聚合函数。
● HAVING - 演示如何过滤分组中的行记录。
子查询
● 子查询 - 介绍子查询的概念以及如何使用子查询来执行高级数据选择技术。
● 相关子查询 - 了解相关的子查询,它是一个依赖于外部查询返回的值的子查询。
● EXISTS和NOT EXISTS - 检查子查询返回的行是否存在。
● ANY,SOME和ALL - 将值与列表或子查询进行比较。
设置操作符
本节介绍使用集合运算符合并两个或多个独立查询的结果集的步骤。
● UNION - 演示如何将两个查询的结果合并为一个结果。
● INTERSECT - 演示如何实现两个独立查询的结果的交集。
● MINUS - 学习如何从一个结果集中减去另一个结果(也就是求差集)。
修改数据
在本节中,将学习如何更改Oracle数据库的数据内容。用于修改数据的SQL命令被称为数据操纵语言(DML)。
● INSERT - 学习如何在表中插入一行。
● INSERT INTO SELECT - 从查询结果中将数据插入到表中。
● INSERT ALL - 讨论多重插入语句,将多行插入到一个或多个表中。
● UPDATE - 演示如何更新表的存在的数据值。
● DELETE - 演示如何从表中删除一行或多行。
● MERGE - 使用单个语句逐步完成插入,更新和删除操作。
数据定义
本节介绍如何管理数据库和表的最重要的数据库对象。
● CREATE TABLE - 演示如何在数据库中创建新表。
● IDENTITY列 - 了解如何使用IDENTITY子句来定义表的标识列。
● ALTER TABLE - 演示如何改变表的结构。
● ALTER TABLE ADD列 - 显示如何将一个或多个列添加到现有表
● ALTER TABLE MODIFY列 - 演示如何更改表中现有列的定义。
● DROP COLUMN - 了解如何使用各种语句从表中删除一列或多列。
● DROP TABLE - 演示如何从数据库中删除表。
● TRUNCATE TABLE - 更快,更有效地删除表中的所有数据。
● RENAME TABLE - 学习如何重命名表和处理其依赖对象的过程。
Oracle数据类型
● Oracle数据类型 - 内置Oracle数据类型的概述。
● NUMBER - 介绍数字数据类型,并展示如何使用它为表定义数字列。
● FLOAT - 通过实例来解释Oracle中的浮点数据类型。
● CHAR - 了解固定长度的字符串类型。
● NCHAR - 演示如何存储固定长度的Unicode字符数据,并解释CHAR和NCHAR数据类型之间的区别
● VARCHAR2 - 向您介绍可变长度字符,并向您展示如何在表中定义可变长度字符列。
● NVARCHAR2 - 了解如何在数据库中存储可变长度的Unicode字符。
● DATE - 讨论日期和时间数据类型,并说明如何有效地处理日期时间数据。
● TIMESTAMP - 介绍如何以小数秒精度存储日期和时间。
● INTERVAL - 介绍区间数据类型,主要用来存储时间段。
● TIMESTAMP WITH TIME ZONE - 了解如何使用时区数据存储日期时间。
约束
● 主键 - 解释主键概念,并演示如何使用主键约束来管理表的主键。
● 外键 - 解释介绍外键概念,并演示如何使用外键约束来强制表之间的关系。
● NOT NULL约束 - 演示如何确保列不接受NULL值。
● UNIQUE约束 - 讨论如何确保存储在一列或一组列中的数据在整个表内的行之间是唯一的。
● CHECK约束 - 在将数据存储到表中之前添加用于检查数据的逻辑的过程。
1、实用sql
https://www.cnblogs.com/hanease/p/15690069.html
2、sql优化
https://www.cnblogs.com/hanease/p/15690255.html
1、查询SQL尽量不要使用select *,而是select具体字段。
2、如果知道查询结果只有一条或者只要最大/最小一条记录,建议用limit 1
3、应尽量避免在where子句中使用or来连接条件 使用union all
4、优化limit分页
//方案一 :返回上次查询的最大记录(偏移量) select id,name from employee where id>10000 limit 10.//方案二:order by + 索引 select id,name from employee order by id limit 10000,10//方案三:在业务允许的情况下限制页数:5、优化你的like语句 like '123%';
6、使用where条件限定要查询的数据,避免返回多余的行
7、尽量避免在索引列上使用mysql的内置函数
8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫
9、Inner join 、left join、right join,优先使用Inner join,如果是left join,左边表结果尽量小
10、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
11、使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则。
12、对查询进行优化,应考虑在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描。
13、如果插入数据过多,考虑批量插入。
14、在适当的时候,使用覆盖索引。
15、慎用distinct关键字
16、删除冗余和重复索引
17、如果数据量较大,优化你的修改/删除语句。
18、where子句中考虑使用默认值代替null。
19、不要有超过5个以上的表连接
20、exist & in的合理利用
21、尽量用 union all 替换 union
22、索引不宜太多,一般5个以内。
23、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型
24、索引不适合建在有大量重复数据的字段上,如性别这类型数据库字段。
25、尽量避免向客户端返回过多数据量。
26、当在SQL语句中连接多个表时,请使用表的别名,并把别名前缀于每一列上,这样语义更加清晰。
27、尽可能使用varchar/nvarchar 代替 char/nchar。
28、为了提高group by 语句的效率,可以在执行到该语句前,把不需要的记录过滤掉。
29、如何字段类型是字符串,where时一定用引号括起来,否则索引失效
30、使用explain 分析你SQL的计划
3、数据库的优化
数据库的优化是一个综合型的技术,并不是通过某一种方式让数据库效率提高很多, 而使通过多方便的提高,从而使数据提高很多
主要包括
1. 表的设计合理化
2. SQL语句的优化
3. 给表要添加合适的索引 普通索引、主键所以,唯一索引 unique、全文索引
4. 分表技术(水平分割、垂直分割)
5. 定时清除垃圾数据、定时进行碎片整理
6. 多用存储过程,和触发器
7. 对mysql的配置进行优化[配置最大并发数my.ini,调整缓存大小]
8. 读写分离
9. myql服务器硬件是否要升级
表的设计合理化
三范式:
第一范式、
确保每列的原子性、所有的(不可再分)
注意:地址这个字段,如果不分类汇总,不排序,仅仅是起一个字符串的作用,这是我们不拆分(反三范式)
第二范式、
非键字段必须依赖与键字段(一个表做一件事情)
第三范式、
消除传递依赖(如果一个字段可以推到出到另外一个字段)
反三范式:
范式越高,数据的冗余就越少、但是有的时候效率就越底下,为了提高运行效率,可以适当
的适当的让数据的冗余。
数据库的性能比规范化更重要
SQL语句的优化
定位慢查询
增、删、改、查
一、MySql数据库一个关于状态的查询
show status指令 查询mysql的运行状态
show status like ‘com_insert’ 执行了多少次插入
show status like ‘com_update’ 执行了多少次更新
show status like ‘com_delete’ 执行了多少次删除
show status like ‘com_select’ 执行了多少次删除
show[session | global ] status like com_select’
show status like ''uptime' 显示MySql数据库启动多长时间,如果时间很长了,
数据库表的存储引擎是myisan的,这时候就要主要整理碎片。
二、显示慢查询
show variables like 'long_query_time'
set long_query_time = 0.5
show status like 'slow_queries'
定位慢查询(开启慢查询的日志)
一旦开启慢查询日志后,日志文件的位置,在my.ini文件去查找datadir
在默认情况下不会开启慢查询,如何开启慢查询呢
第一步: 关闭当前的MySql的服务
第二步: 启动 mysqld --safe -mode --slow-query-log
关闭 mysqladmin -uroot -p123456 shut down
优化问题
通过explain语句可以分析,mysql如何执行的sql语句
二、数据库的索引
一、建立适当的索引
高数据库性能,索引是最物美价廉的东西了,不用加内存,不用改变调用sql,只要执行正确的create index 查询速度就可能提高百倍千倍
二、添加索引
主键索引
当一张表中某个列设为主键的时候,则该列就是主键索引
create table aa(id int unsigned primary key auto_increment,
name varchar(32) )
这是id列是主键例
第一种 : 查询索引 desc 表名 不能显示索引的名字
第二种 : 查询索引的show index from 表名
第三种 : 查询索引的show keys from 表名、
如果你创建不表的时,没有指定主键索引,也可以在创建表后,在添加指令
alter table 表名 add primary key(列名);
emp.frm 表的结构
emp.MYD 表的数据
emp.MYI 表的索引
普通索引
普通索引的创建,是先创建表,然后添加索引
create index 索引的名字 on 表名(列)
唯一索引
当变的某列指定为unique约束时,这列就是一个唯一索引
create table ddd(
id int primary key not null,
name varchar(100) unique
)
全文索引
全文索引、主要是针对文件、文本的检索,全段索引对Myisam
错误的用法
select * from articles where body like '%mysql%'
正确的用法是
select * from articles where match(title,body) aginst('database')
说明
1.在mysql中fulltext索引指针对myisam生效
2.mysql自己提高的fulltest针对英文生效->sphinx(coreseek) 技术处理中文
3.使用方法是match(字段名) against(‘关键字’)
4.全文索引一个叫停止词
删除索引
alter table 表名 drop index 索引名
如果删除主键索引
alter table 表名 drop primary key
修改索引
先删除,在重新创建
为什么创建索引后速度会变快呢 BTree
三、 索引使用的注意事项
磁盘占用
对dml(update,delete,insert)语句的效率影响
频繁操作的适合建立索引,字段非频繁不适合建立索引,更新次数多的不适合建立索引
说明,如果我们的表中使用有复合索引(索引作用在多列上),此时我们
注意
1>对于创建得多列索引,只要查询条件使用了最左边的列,索引一段就会
被使用。
explain select * from dept where loc ="xxx"
2>对于使用like查询,查询如果是'%AA' 不会使用到索引‘aaa%’
会使用到索引
比如: explain select * from dept where dname like '%AAA'
不能使用 索引,既在like查询时,关键字,最前面,不能使用%或则)_这样
的字符,如果一定要前面有变化的值,则考虑使用全文检索->sphinx
3>如果条件中有or 即使用其中有条件带索引也不会使用,换言之,就是
要求使用所字段,都必须建立索引
id : 查询序列号
select_type:查询的类型
table:查询的表名
type:扫描的方式
possible_keys:这个表中可能使用了哪些索引
key 实际使用了哪些索引
key_len:
ref
rows:扫描了多少行数,可能得到多少记录
extra:sql语句额外信息,排序方式
索引的使用
查看索引的是使用情况
show status like 'Handler_read%';
大家可以注意
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
handler_read_rnd_next:这个值越高,说明查询低效
常用SQL优化
大批量插入数据(MySql管理员)
对于MyISAM
alter table table_name disable keys
loading dataa
alter table table_name enable keys;
对于Innodb
对于
1.将到导入的数据按照主键排序
2.set unique_checks= 0,关闭唯一性校验
3. set autocommit = 0,关闭自动提交
sql语句的小技巧
1> 在使用group by 分组查询,默认分组后,还会排序,可能会降低速度
2> 在group by 后面添加order by null 就不会排序
3> 在有些情况下,可以使用连接代替子查询,因为使用join MySql不需要在内存中
创建临临时表
select * from dept,emp where dept.deptno = emp.deptno
select * from dept left join emp on dept.deptno = emp.deptno
选择合适的存储引擎
myIsam 存储,如果表对事物要求不高,同时是以查询和添加为主的,我们考虑使用
myisan存储引擎
INNODB 存储,对事物要求高,保存的数据都是重要数据
memory: 存储,比如我们数据变法频繁,不需要入库,同时又频繁查询和修改,我们考试
使用memory
myisam innodb
批量插入的速度 高 低
事物安全 支持
全文索引 支持
锁机制 表锁 行锁
存储限制 没有 64TB
B数索引 没有 支持
哈希索引 支持
集群索引 支持
数据缓存 支持 支持
索引缓存 支持
数据可压缩 支持
空时使用 低 高
内存使用 低 高
支持外键
MyISaM 与 innodb
1.事物安全
2.查询和添加速度
3.支持全文索引
4.锁机制
5.外键MyISAM不支持外键
MyISaM删除数据文件变小
optimize table 表名
定时维护
三、数据库备份
一、手动数据库(表的)方法
cmd 控制台
mysqldump -uroot -proot 数据库[表名1 表名2] > 文件路径
比如 吧temp 数据库备份到d \temp bak
mysqldump -u root -proot temp>d:\temp.bak
二、如何使用备份文件恢复我的数据
在mysql环境
source d:\temp.bak
使用定时器来定时完成
一、在windows系统
mytask.bak 文件
mysqldump -u root -proot temp>d:\temp.bak
注意:
注意
1> 如果路径里面有空格需要加入双引号
2> mysqlump 写全路径
定时任务
windwxp
控制面板---> 任务计划
二、在linux系统
现在问题是,每次都是覆盖原来的备份文件,不利用我们分时间段进行备份,
crontab corn 表达式
理解事务的4种隔离级别 读
1.Read uncommitted (脏读)
读未提交
就是一个事务可以读取另一个未提交事务的数据。
2.Read committed (不可重复读) 读取两次数据不一致
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
如果对事物进行update操作时,读操作事物要等待这个更新操作事物提 交后才能读取数据,可以解决脏读问题
3.Repeatable read (幻读)读取两次数据一致
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
4.Serializable 序列化
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
一、什么数据库的事物
原子性、一致性、格力性、持久性
原子性(ATOMICITY)
一个事物必须视为一个不可分割的最小工作单元,整个事物中额所有操作
要么全部提交成功,要么全部失败,对于一个事物来说,不可能只执行其中
一部分操作。
一致性
一致性是指事物将数据库从一种一致性状态装换到另外一种一致性状态
,在事物开始之前和事物结束后数据库中数据的完整性没有破坏。
事物的隔离型(ISOLATION)
隔离性要求一个事物对数据库中数据的修改没再未提交完成前对于其他事物
是不可见的
事物的持久性
一旦事物提交,则其所做的修改就会永远保存到数据库中
什么是大事物
运行事物比较长,操作的数据比较多的事物
风险
锁定太多的数据、造成主从延迟大量的阻塞和锁超时回滚时所需时间比较长
回滚时所需时间比较上
执行时间长、容易造成主从延迟
1.避免一次处理大多的数据
2.移除不必要的查询操作
十、影响数据库性能
一、磁盘IO
风险
磁盘IO性能突然下降(使用更快的磁盘设备)
其他大量消耗磁盘性能的计划任务(调整计划任务,做好磁盘维护)
二、QPS和TPS
三、网卡流量
如何避免无法连接数据库的情况
1.减少从服务器的数据
2.进行分级缓存
3.避免使用select * 进行查询
4.分离业务网络和服务器网络
四、大表
一、可以称为大表
1.记录行数巨大,单表超过千万行
2.表的额数据文件巨大,表数据文件超过10G
二、大表查询的影响
慢查询:很难在一定的时间内过滤出所需要额数据
大表对DDL操作影响
风险
MySQL版本< 5.5 建立索引会锁表
MySQL版本 > = 5.5虽然不会锁表但会引起主从延迟
修改表结构需要长时间锁表
长时间的主从延迟
影响正常的数据操作
如何处理数据库中的大表
分库分表把一张大表分成多个小表
难点
分表主键的选择
分表后跨跨分区数据的查询和统计
大表的历史数据归档
减少对前端后端业务的影响
难点
1.归档的时间点的选择
2.如何进行归档操作
一、把一个实例中多个数据库查分到不同的实例
例如
MySQL节点一
订单 ---------用户---------------促销
订单节点node01
用户节点node02
促销节点node03
不能解决写负载----->
二、把一个库中表分离到不同的数据库中
订单节点node01 拆分到不同的节点中
订单表
商品表
购物表
三、数据库分片前的准备
如何选择分区键
1.要尽量避免跨分区查询的发生
2.分片键要尽可能使各个分片中的数据平均
如何无需分片的表
每个分片中存储一份相同的数据
使用额外的节点统一存储
如何在节点上部署分片
在每个分片使用单一数据库。并且数据库也相同
将多个分片存储在一个数据库中,并在表名上加入分片号后缀
在一个节点中部署多个数据库,每个数据库包含一个分片
数据库分片前的准备
如何分配分片中的数据
按分区键的Hash值取模来分配分片数据
按照区键的范围来分配分片数据
利用分区键和分片的映射表来分配分片数据
-----------------------------
数据库对比
ORDBMS 术语
- 数据库: 数据库是一些关联表的集合。
- 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
- 列: 一列(数据元素) 包含了相同的数据, 例如邮政编码的数据。
- 行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
Mysql特性
- 使用 C和 C++编写,并使用了多种编译器进行测试,保证了源代码的可移植性。
- 支持 AIX、FreeBSD、HP-UX、Linux、Mac OS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris、Windows等多种操作系统。
- 为多种编程语言提供了 API。这些编程语言包括 C、C++、Python、Java、Perl、PHP、Eiffel、Ruby,.NET和 Tcl 等。
- 支持多线程,充分利用 CPU 资源。
- 优化的 SQL查询算法,有效地提高查询速度。
- 既能够作为一个单独的应用程序应用在客户端服务器网络环境中,也能够作为一个库而嵌入到其他的软件中。
- 提供多语言支持,常见的编码如中文的 GB 2312、BIG5,日文的 Shift_JIS等都可以用作数据表名和数据列名。
- 提供 TCP/IP、ODBC 和 JDBC等多种数据库连接途径。
- 提供用于管理、检查、优化数据库操作的管理工具。
- 支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
- 支持多种存储引擎。
- MySQL 是开源的,所以你不需要支付额外的费用。
- MySQL 使用标准的 SQL数据语言形式。
- MySQL 对 PHP 有很好的支持,PHP是目前最流行的 Web 开发语言。
- MySQL是可以定制的,采用了 GPL协议,你可以修改源码来开发自己的 MySQL 系统。
- 在线 DDL/更改功能,数据架构支持动态应用程序和开发人员灵活性(5.6新增)
- 复制全局事务标识,可支持自我修复式集群(5.6新增)
- 复制无崩溃从机,可提高可用性(5.6新增)
- 复制多线程从机,可提高性能(5.6新增)
- 3倍更快的性能(5.7新增)
- 新的优化器(5.7新增)
- 原生JSON支持(5.7新增)
- 多源复制(5.7新增)
- GIS的空间扩展(5.7新增)
Mysql存储引擎
- MyISAM MySQL 5.0 之前的默认数据库引擎,最为常用。拥有较高的插入,查询速度,但不支持事务.
- InnoDB事务型数据库的首选引擎,支持ACID事务,支持行级锁定, MySQL 5.5 起成为默认数据库引擎.
- BDB源 自 Berkeley DB,事务型数据库的另一种选择,支持Commit 和Rollback 等其他事务特性
- Memory所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在 MySQL 重新启动时丢失
- Merge将一定数量的 MyISAM 表联合而成一个整体,在超大规模数据存储时很有用
- Archive非常适合存储大量的独立的,作为历史记录的数据。因为它们不经常被读取。Archive 拥有高效的插入速度,但其对查询的支持相对较差
- Federated将不同的 MySQL 服务器联合起来,逻辑上组成一个完整的数据库。非常适合分布式应用
- Cluster/NDB高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性。适合数据量大,安全和性能要求高的应用
- CSV 逻辑上由逗号分割数据的存储引擎。它会在数据库子目录里为每个数据表创建一个 .csv 文件。这是一种普通文本文件,每个数据行占用一个文本行。CSV 存储引擎不支持索引。
- BlackHole 黑洞引擎,写入的任何数据都会消失,一般用于记录 binlog 做复制的中继
- EXAMPLE 存储引擎是一个不做任何事情的存根引擎。它的目的是作为 MySQL 源代码中的一个例子,用来演示如何开始编写一个新存储引擎。同样,它的主要兴趣是对开发者。EXAMPLE 存储引擎不支持编索引。另外,MySQL 的存储引擎接口定义良好。有兴趣的开发者可以通过阅读文档编写自己的存储引擎。
PostgreSQL 特征
-
函数:通过函数,可以在数据库服务器端执行指令程序。
-
索引:用户可以自定义索引方法,或使用内置的 B 树,哈希表与 GiST 索引。
-
触发器:触发器是由SQL语句查询所触发的事件。如:一个INSERT语句可能触发一个检查数据完整性的触发器。触发器通常由INSERT或UPDATE语句触发。 多版本并发控制:PostgreSQL使用多版本并发控制(MVCC,Multiversion concurrency control)系统进行并发控制,该系统向每个用户提供了一个数据库的"快照",用户在事务内所作的每个修改,对于其他的用户都不可见,直到该事务成功提交。
-
规则:规则(RULE)允许一个查询能被重写,通常用来实现对视图(VIEW)的操作,如插入(INSERT)、更新(UPDATE)、删除(DELETE)。
-
数据类型:包括文本、任意精度的数值数组、JSON 数据、枚举类型、XML 数据
等。 -
全文检索:通过 Tsearch2 或 OpenFTS,8.3版本中内嵌 Tsearch2。
-
NoSQL:JSON,JSONB,XML,HStore 原生支持,至 NoSQL 数据库的外部数据包装器。
-
数据仓库:能平滑迁移至同属 PostgreSQL 生态的 GreenPlum,DeepGreen,HAWK 等,使用 FDW 进行 ETL。
PostgreSQL支持大部分 SQL 标准并且提供了许多现代特性:
- 复杂查询
- 外键
- 触发器
- 可更新视图
- 事务完整性
- 多版本并发控制
扩展, 通过增加新的:
- 数据类型
- 函数
- 操作符
- 聚集函数
- 索引方法
- 过程语言
oracle特征
Oracle 是一种高效率、可靠性好的、适应高吞吐量的数据库解决方案。
Oracle 数据库主要有四个版本,如下所示。
- 企业版:它是最强大和最安全的版本。它提供所有功能,包括卓越的性能和安全性。
- 标准版:它为不需要企业版强大软件包,提供用户基本功能。
- 易捷版(XE):它是轻量级,免费且有限的 Windows 和 Linux 版本。
- Oracle Lite:专为移动设备而设计。
ORACLE 数据库系统能够在业内独占鳌头并不是空穴来风,下面我们来细数一下 ORACLE 数据库的优势所在:
1. 完整的数据管理功能:
- 数据的大量性
- 数据的保存的持久性
- 数据的共享性
- 数据的可靠性
2. 完备关系的产品:
- 信息准则---关系型DBMS的所有信息都应在逻辑上用一种方法,即表中的值显式地表示
- 保证访问的准则
- 视图更新准则---只要形成视图的表中的数据变化了,相应的视图中的数据同时变化
- 数据物理性和逻辑性独立准则
3. 分布式处理功能:ORACLE数据库自第5版起提供了分布式处理能力,到第7版有比较完善的分布式数据库功能了,一个ORACLE分布式数据库由oraclerdbms、sql*Net、SQL*CONNECT和其他非ORACLE的关系型产品构成。
4. 用ORACLE能轻松的实现数据仓库的操作。
以上是Oracle数据库的优势,从这些优势中不难看出这是一款功能强大的数据库系统。
优点:
- 可用性强
- 可扩展性强
- 数据安全性强
- 稳定性强
- 开放性:oracle可以在所有主流的平台上运行,完全支持工业标准对开发商全力支持
- 安全性:获得最高认证级别的ISO标准认证
- 客户端支持以及应用模式:Oracle多层次网路计算机支持多种工业标准用ODBC,JDBC,OCI等网路客户链接
- 使用风险:Oracle长时间使用向下兼容得到广泛使用的风险
缺点:
- 对硬件要求高,价格也比较贵,管理也麻烦 操作比较复杂,技术要求比较高
数据文件(dbf)
数据文件是数据库的物理存储单位,而表空间TableSpace则是数据库的逻辑组成部分。数据库的数据是存储在表空间中的,而一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属于的表空间才行。
表空间
表空间是 Oracle 对物理数据库上相关数据文件(ORA 或者 DBF 文件)的逻辑映射。一个数据库在逻辑上被划分成一到若干个表空间,每个表空间包含了在逻辑上相关联的一组结构。每个数据库至少有一个表空间(称之为 system 表空间)。每个表空间由同一磁盘上的一个或多个文件组成,这些文件叫数据库文件(datafile)。一个数据文件只能属于一个表空间。
用户
用户是在实例下建立的。不同实例中可以建相同名字的用户。注意!表的数据,是由用户放入某一个表空间的,而这个表空间会随机把这些表数据放到一个或者多个数据文件中。由于 Oracle 的数据库不是普通的概念,oracle 是由用户和表空间对数据进行管理和存放的。但是表不是由表空间去查询的,而是由用户去查的。
数据库语言的分类
DDL:数据库定义语言:create、drop
DML:数据库的操作语言:insert、update、delete
DQL:数据库的查询语言:select
DCL:数据库的控制语言:grant、revoke
oracle数据库的优势
ORACLE 数据库系统能够在业内独占鳌头并不是空穴来风,下面我们来细数一下 ORACLE 数据库的优势所在:
完整的数据管理功能:
- 数据的大量性
- 数据的保存的持久性
- 数据的共享性
- 数据的可靠性
完备关系的产品:
- 信息准则---关系型 DBMS 的所有信息都应在逻辑上用一种方法,即表中的值显式地表示
- 保证访问的准则
- 视图更新准则---只要形成视图的表中的数据变化了,相应的视图中的数据同时变化
- 数据物理性和逻辑性独立准则
分布式处理功能:
- ORACLE 数据库自第5版起提供了分布式处理能力,到第7版有比较完善的分布式数据库功能了,一个ORACLE 分布式数据库由 oraclerdbms、sql*Net、SQL*CONNECT 和其他非 ORACLE 的关系型产品构成。
- 用 ORACLE 能轻松的实现数据仓库的操作
以上是 Oracle 数据库的优势,从这些优势中不难看出这是一款功能强大的数据库系统。
数据库和实例
Oracle 数据库服务器由一个数据库和至少一个数据库实例组成。 数据库是一组存储数据的文件,而数据库实例则是管理数据库文件的内存结构。此外,数据库是由后台进程组成。
数据库和实例是紧密相连的,所以我们一般说的 Oracle 数据库,通常指的就是实例和数据库。
下图说明了 Oracle 数据库服务器体系结构:
-----------------------------
基本架构
1 多进程/多线程架构
MySQL是多线程结构。PostgreSQL是多进程结构。Oracle和平台有关,可认为是多进程/多线程共用的结构。
1.在UNIX平台上,Oracle/PostgreSQL使用多进程模式;MySQL使用单进程多线程模式。
2.在Windows平台上,Oracle/MySQL使用多线程模式, PostgreSQL用多进程模式。
3.Oracle采用独立的监听进程监听用户的连接请求
4.PostgreSQL采用主进程作为监听用户连接请求
5.MySQL采用主线程作为监听用户连接请求
在后台进程或线程方面:
1. Oracle后台进程包括:数据库写进程Database Writer (DBW0 or DBWn)、日志写进程Log Writer (LGWR)、检查点进程Checkpoint (CKPT)、系统监视器进程System Monitor (SMON)、进程监视器进程Process Monitor (PMON)、归档进程Archiver (ARCn)、恢复进程Recoverer (RECO)、锁管理器进程Lock (LCK0)、队列管理器进程Job Queue (SNPn)、队列监视器进程Queue Monitor (QMNn)、调度器进程Dispatcher (Dnnn)、服务器进程Server (Snnn)。
2. PostgreSQL后台线程包含:主服务进程、系统恢复进程、系统写进程、写日志进程、数据库统计进程、空间清理进程、归档进程、输出信息写进程、流复制进程。
3. MySQL(以InnoDB为默认的存储引擎)后台线程包含: 主线程、 脏页刷出线程、事务回滚线程、IO线程(参数确定,可能有多个)锁超时监控线程(解决死锁)、错误监控线程、InnoDB监控线程(打印输出InnoDB监控信息)、缓存刷出的线程(参数确定,可能有多个)、执行purage协调操作的线程、执行purge执行操作的线程(参数确定,可能有多个)、缓存池加载与导出线程、词典统计收集信息线程、全文检索服务线程、 全文检索并行排序线程(参数确定,可能有多个)、性能监控线程(PFS)、复制相关线程等。
三者的主要差异:PostgreSQL比Oracle多出: 数据库统计进程、空间清理进程、输出信息写进程、流复制线进。比Oracle缺少:系统监视器进程、锁管理进程、队列管理器进程、队列监视器进程、调度器进程。
PostgreSQL对每一个客户连接,产生一个相应服务线程。和客户端是一对一关系。
Oracle根据连接方式的不同,产生专用服务器进程或共享服务器进程。其中,专用服务器进程和客户端是一对一关系,共享服务器进程可以是一对多关系。此外,在共享服务器进程存在前提下,还将有一个数据库调度器进程负责任务分派。
2 内存管理方式
1. PostgreSQL,启动过程中,通过参数shared_buffers从操作系统分配一块内存,作为数据页面缓存,这是Pg对内存的自管理方式。之后,数据库运行期间,所需的内存(如数据页的缓存/日至页的缓存/排序和连接运算使用的缓存/锁使用的内存/临时使用的内存),从进程的全局堆中分配。 这块内存,大小不可在运行期间改变,这是一个弊端。
2. Oracle,启动过程中,通过一些参数的控制,从操作系统分配内存,主要是PGA和SGA。 PGA,Program Global Area,程序全局区,是服务器进程(Server Process)使用的一块包含“数据和控制信息”的内存区域,PGA是非共享的内存,在服务器进程启动或创建时分配,并为Server Process排他访问。 SGA,System Global Area,系统全局区,用于加载数据、对象并保存运行状态和数据库控制信息的一块内存区域,在数据库实例启动时分配,当实例关闭时释放,每个实例都有自己的SGA区。
3. MySQL,启动过程中,通过一些参数的控制,从操作系统分配内存供系统的一些信息使用,但对于数据缓存(最主要的缓存),却不是以统一方式管理的,这点和PG/Oracle等数据库非常不同。MySQL通过join buffer提供对所需数据的读写管理。
MySQL的产品特性
Oracle的产品特性
PostgreSQL的产品特性
PostgreSQL具有以下主要产品特性:
1 标准通用:实用、高效的通用数据库管理系统
PostgreSQL 基于广泛应用的关系数据模型,遵循SQL国际标准。 PostgreSQL 经过大量实际应用的磨合与验证,已成为标准、通用、安全、稳定、实用、高效的数据存储与管理平台。
2 简便易用:图形化交互式管理工具
PostgreSQL 提供了多种图形化交互管理工具,用于对数据库进行方便、高效的管理,如PostgreSQL Manager,phpPgAdmin等。
3 海量存储:强大的大规模数据存储与管理能力
PostgreSQL 结合结构化查询语言的操作能力和过程化语言的数据处理能力,可以有效地支持大规模数据存储与存取,如TB级的数据库的表空间、GB 级的 BLOB 二进制大对象和 CLOB 文本大对象等,并通过各种约束保证数据的完整性和安全性。
4 数据安全:较高的安全性
为应对数据安全保护需求,PostgreSQL V6通过身份鉴别、系统权限、对象权限(表级q权限、列级权限)、用户权限,以及数据访问、传输(利用SSL)等方面的安全性增强提高了数据库系统的整体安全性,可以在一定程度上应对多样的数据安全管理的业务场景,保障数据的安全(但数据的安全,最大的威胁依旧是操作系统)。
5 跨越平台:平台无关性,适用于不同操作系统
PostgreSQL 服务器内核可跨越平台运行在 Windows、Linux、UNIX 等操作系统之上。
6 标准接口:标准化应用接口
PostgreSQL 为应用开发提供了符合标准的 ODBC 3.0、JDBC 3.0、OLEDB 2.7和嵌入式 SQL 接口,应用软件开发者可使用常用的各种开发工具,通过这些接口,进行复杂的商业应用开发。PostgreSQL 服务器端的服务进程与客户端应用通过标准的TCP/IP接口通信。SQL语言符合SQL:1992标准的入门级和过渡级,SQL:1999和SQL:2003的核心级。
7 支持数据库核心功能。
7.1 真正的事务型数据库,完全支持ACID四大特性。
7.2 数据库完整性支持良好,主外键特性完善(实体完整性,参照完整性)。约束特性完善(用户自定义完整性)。
7.3 用户可定义的对象类型丰富。包括:数据库,模式,表,视图,索引,各种约束(NOT NULL/主外键/CHECK),触发器,储存过程,用户自定义函数。丰富的数据类型。
7.4 用户可定义内存空间。数据缓存区的管理(设置share_buffer变量)。
7.5 存储:用户可定义存储位置,但表空间的管理方式有待继续完善(适用到V9.4)。
7.6 并发的支持:MVCC实现并发读不冲突。各种锁(自旋锁,轻量锁,锁)和各种对象的不同级别的锁(读锁,写锁,意向锁)的实现保护了竞争的相同资源。
7.7 查询优化技术的支持。高效的查询优化器和执行器,保证了查询执行的效率。
时间序列数据库TSDB InfluxDB介绍
时间序列模型
时间序列数据库主要用于指处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据。
每个时序点结构如下:
-
timestamp: 数据点的时间,表示数据发生的时间。
-
metric: 指标名,当前数据的标识,有些系统中也称为name。
-
value: 值,数据的数值,一般为double类型,如cpu使用率,访问量等数值,有些系统一个数据点只能有一个value,多个value就是多条时间序列。有些系统可以有多个value值,用不同的key表示
-
tag: 附属属性。
实现
比如我想记录一系列传感器的时间序列数据。数据结构如下:
* 标识符:device_id,时间戳
* 元数据:location_id,dev_type,firmware_version,customer_id
* 设备指标:cpu_1m_avg,free_mem,used_mem,net_rssi,net_loss,电池
* 传感器指标:温度,湿度,压力,CO,NO2,PM10
如果使用传统RDBMS存储,建一张如下结构的表即可:
如此便是一个最简单的时间序列库了。但这只是满足了数据模型的需要。我们还需要在性能,高效存储,高可用,分布式和易用性上做更多的事情。
大家可以思考思考,如果让你自己来实现一个时间序列数据库,你会怎么设计,你会考虑哪些性能上的优化,又如何做到高可用,怎样做到简单易用。
1、时间序列数据库 TSDB
时间序列数据库 (Time Series Database , 简称 TSDB) 是一种高性能、低成本、稳定可靠的在线时间序列数据库服务,提供高效读写、高压缩比存储、时序数据插值及聚合计算等服务,广泛应用于物联网(IoT)设备监控系统、企业能源管理系统(EMS)、生产安全监控系统和电力检测系统等行业场景;除此以外,还提供时空场景的查询和分析的能力。
TSDB 具备秒级写入百万级时序数据的性能,提供高压缩比低成本存储、预降采样、插值、多维聚合计算、可视化查询结果等功能,解决由设备采集点数量巨大、数据采集频率高造成的存储成本高、写入和查询分析效率低的问题。
TSDB是一个分布式时间序列数据库,具备多副本高可用能力。同时在高负载大规模数据量的情况下可以方便地进行弹性扩容,方便用户结合业务流量特点进行动态规划与调整。
应用场景
物联网设备无时无刻不在产生海量的设备状态数据和业务消息数据,这些数据有助于进行设备监控、业务分析预测和故障诊断。
背景信息
设备将原始数据通过 MQTT 协议发送到物联网平台,经由物联网平台将数据转发到消息服务系统,继而通过流计算系统对这些数据进行实时计算处理后写入到 TSDB 中存储,或者经由物联网平台直接将原始数据写入 TSDB 中存储。前端的监控系统和大数据处理系统会利用 TSDB 的数据查询和计算分析能力进行业务监控和分析结果的实时展现。
名词解释
-
时间序列数据库 TSDB :英文全称为 Time Series Database,提供高效存取时序数据和统计分析功能的数据管理系统。
-
时序数据(Time Series Data):基于稳定频率持续产生的一系列指标监测数据。例如,监测某城市的空气质量时,每秒采集一个二氧化硫浓度的值而产生的一系列数据。
-
度量(Metric):监测数据的指标,例如风力和温度。
-
标签(Tag):度量(Metric)虽然指明了要监测的指标项,但没有指明要针对什么对象的该指标项进行监测。标签(Tag)就是用于表明指标项监测针对的具体对象,属于指定度量下的数据子类别。
一个标签(Tag)由一个标签键(TagKey)和一个对应的标签值(TagValue)组成,例如“城市(TagKey)= 杭州(TagValue)”就是一个标签(Tag)。更多标签示例:机房 = A 、IP = 172.220.XX.XX。
注意:当标签键和标签值都相同才算同一个标签;标签键相同,标签值不同,则不是同一个标签。
在监测数据的时候,指定度量是“气温”,标签是“城市 = 杭州”,则监测的就是杭州市的气温。
-
标签键(TagKey,Tagk):为指标项(Metric)监测指定的对象类型(会有对应的标签值来定位该对象类型下的具体对象),例如国家、省份、城市、机房、IP 等。
-
标签值(TagValue,Tagv):标签键(TagKey)对应的值。例如,当标签键(TagKey)是“国家”时,可指定标签值(TagValue)为“中国”。
-
值(Value):度量对应的值,例如 15 级(风力)和 20 ℃(温度)。
-
时间戳(Timestamp):数据(度量值)产生的时间点。
-
数据点 (Data Point):针对监测对象的某项指标(由度量和标签定义)按特定时间间隔(连续的时间戳)采集的每个度量值就是一个数据点。“一个度量 + N 个标签(N >= 1)+ 一个时间戳 + 一个值”定义一个数据点。
-
时间序列(Time Series):针对某个监测对象的某项指标(由度量和标签定义)的描述。“一个度量 + N 个标签KV组合(N >= 1)”定义为一个时间序列,某个时间序列上产生的数据值的增加,不会导致时间序列的增加。 时间序列的示意图如下:
-
时间线(Timeline):等同于时间序列的概念。
-
时间精度:时间线数据的写入时间精度——毫秒、秒、分钟、小时或者其他稳定时间频度。例如,每秒一个温度数据的采集频度,每 5 分钟一个CPU使用率的采集频度。
-
数据组(Data Group):如果需要对比不同监测对象(由标签定义)的同一指标(由度量定义)的数据,可以按标签这些数据分成不同的数据组。例如,将温度指标数据按照不同城市进行分组查询,操作类似于该 SQL 语句:
select avg(temperature),city from xx where xx group by city
。 -
聚合( Aggregation):当同一个度量(Metric)的查询有多条时间线产生(多个指标采集设备),那么为了将空间的多维数据展现为成同一条时间线,需要进行合并计算,例如,当选定了某个城市某个城区的污染指数时,通常将各个环境监测点的指标数据平均值作为最终区域的指标数据,这个计算过程就是空间聚合。
-
降采样(Downsampling):当查询的时间区间跨度较长而原始数据时间精度较细时,为了满足业务需求的场景、提升查询效率,就会降低数据的查询展现精度,这就叫做降采样,比如按秒采集一年的数据,按照天级别查询展现。
-
数据时效(Data’s Validity Period):数据时效是设置的数据的实际有效期,超过有效期的数据会被自动释放。
相比OpenTSDB优势
OpenTSDB是可扩展的分布式时序数据库,底层依赖HBase。作为基于通用存储开发的时序数据库典型代表,起步比较早,在时序市场的认可度相对较高。阿里云智能TSDB高度兼容OpenTSDB协议,采用自研的索引,数据模型,流式聚合等技术手段提供更强大的时序能力。本文从运维管控,功能,成本,性能等方面对比阿里云智能TSDB和OpenTSDB的优势。
背景信息
OpenTSDB | TSDB | ||
---|---|---|---|
运维管控 | 服务可用性 | 需自行保障,自行搭建集群,自建组件依赖。 | 99.9% |
数据可靠性 | 需自行保障,自行搭建集群,自建组件依赖。 | 99.9999% | |
软硬件投入 | 数据库服务器成本相对较高。 | 无软硬件投入,按需付费。 | |
维护成本 | 需招聘专职TSDB DBA人员来维护,花费大量人力成本。 | 托管服务。 | |
部署扩容 | 需硬件采购、机房托管、机器部署等工作,周期较长。 | 即时开通,快速部署,弹性扩容。 | |
依赖组件繁重 | 依赖AysncHBase,HBase等运维成本高。 | 0运维。 | |
配置调优参数繁多 | SALT、连接数,同步刷盘参数,Compaction等等。 | 默认参数采用最佳实践。 | |
建表语句 | 需要运维静态建表语句。 | 建表语句托管,用户透明。 | |
监控报警体系 | 依赖外部搭建。 | 完整的自监控链路。 | |
功能 | 数据模型 | 单值模型。 | 同时支持多值模型和单值模型。 |
SDK | 开源SDK不支持查询。 | 健壮稳定的Java SDK。 | |
数据类型多样性 | 数值类型。 | 支持数值,布尔,字符串等多种数据类型。 | |
SQL查询能力 | 不具备。 | 支持SQL的分析查询。 | |
管理控制台 | 内置简单的图形展示。 | 支持丰富的详情展示,数据管理,时序洞察等。 | |
中文支持 | 仅支持英文字符。 | 支持英文字符和中文字符。 | |
单一维度(tags 可选择) | tags是必选参数。 | tags是可选参数。 | |
TagKey个数 | 最多8个。 | 可支持16个。 | |
集成能力 | 开源产品,与云产品集成能力弱。 | 同Flink,物联网平台无缝对接,生态丰富。 | |
成本 | 数据压缩 | 通用压缩,压缩率低。 | 时序领域专用压缩,压缩率高。 |
稳定性 | 数据读取 | 读写耦合,容易造成连接数耗尽,读写失败概率大。 | 读写线程池分离,易于管理连接,读写稳健。 |
聚合器 | 内存物化聚合,容易造内存OOM。 | 流式聚合,内存管理粒度细,可控性强。 |
--------------------------------------------
二、设计篇
1、NoSQL和SQL的区别、使用场景与选型比较
什么是NoSQL
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称,它具有非关系型、分布式、不提供ACID的数据库设计模式等特征。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
SQL 和 NoSQL 的区别

SQL数据库适合那些需求确定和对数据完整性要去严格的项目。NoSQL数据库适用于那些对速度和可扩展性比较看重的那些不相关的,不确定和不断发展的需求。简单来说就是:
- SQL是精确的。它最适合于具有精确标准的定义明确的项目。典型的使用场景是在线商店和银行系统。
- NoSQL是多变的。它最适合于具有不确定需求的数据。典型的使用场景是社交网络,客户管理和网络分析系统。
SQL和Nosql的选型和比较
1.关系型数据库和非关系型数据库
SQL (Structured Query Language) 数据库,指关系型数据库。主要代表:SQL Server,Oracle,MySQL等。
NoSQL(Not Only SQL)泛指非关系型数据库,主要代表:MongoDB,Redis等。
2.关系型数据库适合存储结构化数据
如用户的帐号、地址等:
1)这些数据通常需要做结构化查询,比如join,这时候,关系型数据库就要胜出一筹
2)这些数据的规模、增长的速度通常是可以预期的
3)保证数据的事务性、一致性要求。
3.NoSQL适合存储非结构化数据
如发微博、文章、评论:
1)这些数据通常用于模糊处理,如全文搜索、机器学习
2)这些数据是海量的,而且增长的速度是难以预期的,
3)根据数据的特点,NoSQL数据库通常具有无限(至少接近)伸缩性
4)按key获取数据效率很高,但是对join或其他结构化查询的支持就比较差
目前许多大型互联网项目都会选用MySQL(或任何关系型数据库) + NoSQL的组合方案。
NoSQL的常见4大类型和比较
有四种常见的 NoSQL 数据库类型:列式、文档、图形和内存键值。

1.列式数据
顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
1)对应的nosql: HBase,BigTable等。
2)典型应用场景:按列存储,针对某一列或者某几列的查询有非常大的IO优势。
3)优点:查找速度快,可扩展性强,更容易进行分布式扩展。
4)缺点:功能相对局限。
2.文档数据库
旨在将半结构化数据存储为文档,通常采用 JSON 或 XML 格式。与传统关系数据库不同的是,每个 NoSQL 文档的架构是不同的,可让您更加灵活地整理和存储应用程序数据并减少可选值所需的存储。
1)对应的nosql:CouchDB, MongoDb
2)典型应用场景:存储类似JSON格式的内容,可对某些字段建立索引功能,是最像关系型的数据库。
3)优点:数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构。
4)缺点:查询性能不高,而且缺乏统一的查询语法。
3.图形数据库
可存储顶点以及称为边缘的直接链路。图形数据库可以在 SQL 和 NoSQL 数据库上构建。顶点和边缘可以拥有各自的相关属性。
1)数据模型:图结构
2)典型应用场景:社交网络,推荐系统等。专注于构建关系图谱,善于处理大量复杂、互连接、低结构化的数据,数据往往变化迅速,且查询频繁。
3)优点:利用图结构相关算法。比如最短路径寻址,N度关系查找等。
4)缺点:很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。
4.内存键值存储
可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收,是针对读取密集型应用程序工作负载(例如社交网络、游戏、媒体共享和 Q&A 门户)。内存缓存可将重要数据存储在内存中以实现低延迟访问,从而提高应用程序性能。
1)对应的nosql:Redis,Memcached等
2)典型应用场景:内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。
3)优点:查找速度快。
4)缺点:数据无结构化,通常只被当作字符串或者二进制数据。
---------------------------
1、HBase、Redis、MongoDB、Couchbase、LevelDB主流 NoSQL 数据库的对比
HBase
HBash 的数据存储是基于列(ColumnFamily)的,且非常松散—— 不同于传统的关系型数据库(RDBMS),HBase 允许表下某行某列值为空时不做任何存储(也不占位),减少了空间占用也提高了读性能。
属于CP类型
优势
1. 存储容量大,一个表可以容纳上亿行,上百万列;
2. 可通过版本进行检索,能搜到所需的历史版本数据;
3. 负载高时,可通过简单的添加机器来实现水平切分扩展,跟Hadoop的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性能(MapReduce);
4. 在第3点的基础上可有效避免单点故障的发生。
缺点
1. 基于Java语言实现及Hadoop架构意味着其API更适用于Java项目;
2. node开发环境下所需依赖项较多、配置麻烦(或不知如何配置,如持久化配置),缺乏文档;
3. 占用内存很大,且鉴于建立在为批量分析而优化的HDFS上,导致读取性能不高;
4. API相比其它 NoSql 的相对笨拙。
适用场景
1. bigtable类型的数据存储;
2. 对数据有版本查询需求;
3. 应对超大数据量要求扩展简单的需求。
---------------------------Redis
Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。目前由VMware主持开发工作。优势
1. 非常丰富的数据结构;
2. Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断;
3. 数据存在内存中,读写非常的高速,可以达到10w/s的频率。
缺点
1. Redis3.0后才出来官方的集群方案,但仍存在一些架构上的问题(出处);
2. 持久化功能体验不佳——通过快照方法实现的话,需要每隔一段时间将整个数据库的数据写到磁盘上,代价非常高;而aof方法只追踪变化的数据,类似于mysql的binlog方法,但追加log可能过大,同时所有操作均要重新执行一遍,恢复速度慢;
3. 由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然redis本身有key过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
适用场景
适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。
---------------------------
MongoDB
MongoDB 是一个高性能,开源,无模式的文档型数据库,开发语言是C++。它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。
在 MongoDB 中,文档是对数据的抽象,它的表现形式就是我们常说的 BSON(Binary JSON )。
MongoDB 比较灵活,可以设置成 strong consistent (CP类型)或者 eventual consistent(AP类型)。
优势
1. 强大的自动化 shading 功能(更多戳这里);
2. 全索引支持,查询非常高效;
3. 面向文档(BSON)存储,数据模式简单而强大。
4. 支持动态查询,查询指令也使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
5. 支持 javascript 表达式查询,可在服务器端执行任意的 javascript函数。
缺点
1. 单个文档大小限制为16M,32位系统上,不支持大于2.5G的数据;
2. 对内存要求比较大,至少要保证热数据(索引,数据及系统其它开销)都能装进内存;
3. 非事务机制,无法保证事件的原子性。
适用场景
1. 适用于实时的插入、更新与查询的需求,并具备应用程序实时数据存储所需的复制及高度伸缩性;
2. 非常适合文档化格式的存储及查询;
3. 高伸缩性的场景:MongoDB 非常适合由数十或者数百台服务器组成的数据库。
4. 对性能的关注超过对功能的要求。
MongoDB特点
模式自由 :可以把不同结构的文档存储在同一个数据库里
面向集合的存储:适合存储 JSON风格文件的形式
完整的索引支持:对任何属性可索引
复制和高可用性:支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目的是提供冗余及自动故障转移
自动分片:支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器
丰富的查询:支持丰富的查询表达方式,查询指令使用JSON形式的标记,可轻易查询文档中的内嵌的对象及数组
快速就地更新:查询优化器会分析查询表达式,并生成一个高效的查询计划
高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)
基本操作
MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成
MongoDB文档类似于JSON对象,字段值可以包含其他文档、数组、文档数组
安装管理mongodb环境
完成数据库、集合的管理
数据的增加、修改、删除、查询
名词
SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins 表连接,MongoDB不支持
primary keyprimary key主键,MongoDB自动将_id字段设置为主键
三元素:数据库,集合,文档
集合就是关系数据库中的表
文档对应着关系数据库中的行
文档,就是一个对象,由键值对构成,是json的扩展Bson形式
{'name':'guojing','gender':'男'}
集合:类似于关系数据库中的表,储存多个文档,结构不固定,如可以存储如下文档在一个集合中
{'name':'guojing','gender':'男'}
{'name':'huangrong','age':18}
{'book':'shuihuzhuan','heros':'108'}
数据库:是一个集合的物理容器,一个数据库中可以包含多个文档
一个服务器通常有多个数据库
---------------------------
Couchbase
本文之所以没有介绍 CouchDB 或 Membase,是因为它们合并了。合并之后的公司基于 Membase 与 CouchDB 开发了一款新产品,新产品的名字叫做 Couchbase。
Couchbase 跟 MongoDB 一样都是面向文档的数据库,不过在往 Couchbase 插入数据前,需要先建立 bucket —— 可以把它理解为“库”或“表”。
Couchbase 明显属于 CP 类型。
优势
1. 高并发性,高灵活性,高拓展性,容错性好;
2. 以 vBucket 的概念实现更理想化的自动分片以及动态扩容(了解更多);
缺点
1. Couchbase 的存储方式为 Key/Value,但 Value 的类型很为单一,不支持数组。另外也不会自动创建doc id,需要为每一文档指定一个用于存储的 Document Indentifer;
2. 各种组件拼接而成,都是c++实现,导致复杂度过高,遇到奇怪的性能问题排查比较困难,(中文)文档比较欠缺;
3. 采用缓存全部key的策略,需要大量内存。节点宕机时 failover 过程有不可用时间,并且有部分数据丢失的可能,在高负载系统上有假死现象;
4. 逐渐倾向于闭源,社区版本(免费,但不提供官方维护升级)和商业版本之间差距比较大。
适用场景
1. 适合对读写速度要求较高,但服务器负荷和内存花销可遇见的需求;
2. 需要支持 memcached 协议的需求。
---------------------------
LevelDB
LevelDB 是由谷歌重量级工程师(Jeff Dean 和 Sanjay Ghemawat)开发的开源项目,它是能处理十亿级别规模 key-value 型数据持久性存储的程序库,开发语言是C++。
除了持久性存储,LevelDB 还有一个特点是 —— 写性能远高于读性能(当然读性能也不差)。
优势
1. 操作接口简单,基本操作包括写记录,读记录和删除记录,也支持针对多条操作的原子批量操作;
2. 写入性能远强于读取性能,
3. 数据量增大后,读写性能下降趋平缓。
缺点
1. 随机读性能一般;
2. 对分布式事务的支持还不成熟。而且机器资源浪费率高。
适应场景
适用于对写入需求远大于读取需求的场景(大部分场景其实都是这样)。
------------------------------------------------
RocksDB-键值存储
存储和访问数百PB的数据是一个非常大的挑战,开源的RocksDB就是FaceBook开放的一种嵌入式、持久化存储、KV型且非常适用于fast storage的存储引擎。
传统的数据访问都是RPC,但是这样的话访问速度会很慢,不适用于面向用户的实时访问的场景。随着fast storage的流行,越来越多的应用可以通过在flash中管理数据并快速直接的访问数据。这些应用就需要使用到一种嵌入式的database。
使用嵌入式的database的原因有很多。当数据请求频繁访问内存或者fast storage时,网路延时会增加响应时间,比如:访问数据中心网络耗时可能就耗费50ms,跟访问数据的耗时一样多,甚至更多。这意味着,通过RPC访问数据有可能是本地直接访问耗时的两倍。另外,机器的core数越来越多,storage-IOPS的访问频率也达到了每秒百万次,传统数据库的锁竞争和context 切换会成为提高storage-IOPS的瓶颈。所以需要一种容易扩展和针对未来硬件趋势可以定制化的database,RocksDB就是一种选择。
RocksDB是基于Google的开源key value存储库LevelDB,主要满足以下目标:
1、适用于多cpu场景
商业服务器一般会有很多cpu核,要开发一个随着CPU 核数吞吐量也随之增大的数据库是很困难的,更别提是线性的递增关系。但是,RocksDB是可以高效地运行在多核服务器上。一个优点是RocksDB提供的语义比传统的DBMS更简单。例如:RocksDB支持MVCC,但是仅限于只读的transaction。另一个优点是数据库在逻辑上分片为read-only path和read-write path。这两种方法可以降低锁竞争,而降低锁竞争是支持高并发负载的前提条件。
2、高校利用storage(更高的IOPS、高效的压缩、更少的写磨损)
现在的存储设备都可以支持到每秒10w的随机读,如果有10块存储卡的话就可以支持每秒100w的随机读。RocksDB可以在这种快速存储上高效运行且不会成为性能瓶颈。
和实时更新的B-tree相比,RocksDB有更好的压缩和更小的写放大。RocksDB由于压缩更优,所以占用更少的storage;由于更小的写放大,flash 设备可以更持久。
3、弹性架构,支持扩展
RocksDB支持扩展。比如,我们可以新增一个merge operator,这样就可以使用write-only来替代read-modify-write。然而,read和Write是会增加存储的读写IOPS。在写频繁的负载下,这种措施可以降低IOPS。
4、支持IO-bound、in-memory、write-once
IO-bound workload是指数据库大小远大于内存且频繁地访问storage。in-memory workload是指数据库数据都在内存中且仍然使用storage来持久化存储DB。write-once workload是指大部分的key都只会写入一次或者insert且没有更新操作。现在RocksDB很好支持IO-bound,要想更好地支持in-memory,需要做一些工作。支持write-once的话,还有很多遗留问题待解决。
RocksDB不是一个分布式的DB,而是一个高效、高性能、单点的数据库引擎。RocksDB是一个持久化存储keys和values的c++ library。keys 和values可以是任意的字节流,且按照keys有序存储。后台的compaction会消除重复的和已删除的key。RocksDB的data以log-structured merge tree的形式存储。RocksDB支持原子的批量写入操作以及前向和后向遍历。
RocksDB采用“可插拔式”的架构,所以很容易替换其中的组件,允许用户很容易在不同的负载和硬件设备上进行调优。
RocksDB的典型场景(低延时访问):
1、需要存储用户的查阅历史记录和网站用户的应用
2、需要快速访问数据的垃圾检测应用
3、需要实时scan数据集的图搜索query
4、需要实时请求Hadoop的应用
5、支持大量写和删除操作的消息队列
------------------------------------------------
KeyDB-键值存储
KeyDB项目是从redis fork出来的分支。众所周知redis是一个单线程的kv内存存储系统,而KeyDB在100%兼容redis API的情况下将redis改造成多线程。
多线程架构
线程模型
KeyDB将redis原来的主线程拆分成了主线程和worker线程。每个worker线程都是io线程,负责监听端口,accept请求,读取数据和解析协议。
KeyDB使用了SO_REUSEPORT特性,多个线程可以绑定监听同个端口。每个worker线程做了cpu绑核,读取数据也使用了SO_INCOMING_CPU特性,指定cpu接收数据。解析协议之后每个线程都会去操作内存中的数据,由一把全局锁来控制多线程访问内存数据。主线程其实也是一个worker线程,包括了worker线程的工作内容,同时也包括只有主线程才可以完成的工作内容。在worker线程数组中下标为0的就是主线程。
------------------------------------------------
DynamoDB-键值存储
Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务,提供快速而可预测的性能,能够实现无缝扩展。DynamoDB 可以从表中自动删除过期的项,从而帮助您降低存储用量,减少用于存储不相关数据的成本。
在DynamoDB中核心组件是表、项目和属性。表是项目的集合,项目是属性的集合,DynamoDB使用主键来标识表中的每个项目,还提供了二级索引来提供更大的查询灵活性,还可以使用DynamoDB流来捕获DynamoDB表中的数据修改事件。
表、项目和属性
- 表 DynamoDB将数据存储在表中,表是某类数据的集合,例如People表、Cars表。
- 项目 每个表包含多个项目,项目是一组属性,具有不同于所有其他项目的唯一标识,项目类似与SQL中的行、记录或元组。
- 属性 每个项目包含一个或多个属性,属性是基本的数据元素,属性类似与SQL中的字段或列。
主键
创建表时除了指定表名外还必须指定表的主键,主键用于唯一标识表中的每一个项目,任意两个项目的主键都不能相同。
DynamoDB支持两种类型的主键:
- 分区键 简单的主键由一个分区键的属性构成,表中的每个项目都必须有不同的分区键值,分区键值用于DynamoDB内部散列(Hash)函数的输入,散列函数的输出决定将项目存储到哪个分区中。
- 分区键和排序键 也称复合键,该类型的主键由两个属性组成, 第一个属性是分区键,第二个属性是排序键,分区键决定存储位置,具有相同分区键的项目按照排序键的值排序然后顺序存储在一起。在具有分区键和排序键的表中两个项目可能有相同的分区键值,但是必须有不同的排序键值。
注意
每个主键属性必须为标量,主键属性的数据类型只能是字符串、数字和二进制。
二级索引
可以在表上建立一个或多个二级索引,利用二级索引,除了可以用主键进行查询外,还可以使用替代键查询表中的数据。
DynamoDB支持两种索引:
- 全局二级索引(Global secondary index) 一种可能带有与表中不同的分区键和排序键的索引
- 本地二级索引(Local secondary index) 一种分区键与表中的相同但排序键与表中不同的索引
------------------------------------------------
BigTable-列族存储
BigTable 其实就是 Google 设计的分布式结构化数据表.
Bigtable 的设计动机:
- 需要存储的数据种类繁多,包括URL、网页内容、用户的个性化设置在内的数据都是Google需要经常处理的
- 需要存储的数据种类繁多海量的服务请求,Google运行着目前世界上最繁忙的系统,它每时每刻处理的客户服务请求数量是普通的系统根本无法承受的.
- 商用数据库无法满足需求,一方面现有商用数据库的设计着眼点在于其通用性。另一方面对于底层系统的完全掌控会给后期的系统维护、升级带来极大的便利
为了解决上述的问题, Google 才提出了 BigTable 的概念.
Bigtable 应达到的基本目标
- 广泛的适用性, Bigtable是为了满足一系列 Google 产品而并非特定产品的存储要求。
- 很强的可扩展性, 根据需要随时可以加入或撤销服务器.
- 高可用性, 确保几乎所有的情况下系统都可用.
- 简单性, 底层系统的简单性既可以减少系统出错的概率,也为上层应用的开发带来便利
Bigtable 数据的存储格式
Bigtable is a sparse, distributed, persistent multidimensional sorted map.
Bigtable 是一个分布式, 多维, 映射表. 表中的数据通过一个行关键字(Row Key)、一个列关键字(Column Key)以及一个时间戳(Time Stamp)进行索引. 在Bigtable中一共有三级索引. 行关键字为第一级索引,列关键字为第二级索引,时间戳为第三级索引。
Bigtable的存储逻辑可以表示为:
(row:string, column:string, time:int64)→string
row 的特点
- Bigtable 的行关键字可以是任意的字符串,但是大小不能够超过 64KB
- 表中数据都是根据行关键字进行排序的,排序使用的是词典序
- 同一地址域的网页会被存储在表中的连续位置
- 倒排便于数据压缩,可以大幅提高压缩率
需要特别注意的是对于一个网站 www.cnn.com 存储在 Bigtable 中的格式是 com.cnn.www
这样倒排的好处是,对于同一域名下的内容,我们可以进行更加快速的索引.
column 的特点
- 将其组织成列族(Column Family)
- 族名必须有意义,限定词则可以任意选定, 比如 “contents”, “title” 等等.
- 组织的数据结构清晰明了,含义也很清楚
- 族同时也是 Bigtable 中访问控制(Access Control)的基本单元
我们从 Bigtable 中读取数据先找到哪一行 然后再去选择读取那个一个 column.
time 的特点
- Google的很多服务比如网页检索和用户的个性化设置等都需要保存不同时间的数据,这些不同的数据版本必须通过时间戳来区分。
- Bigtable中的时间戳是64位整型数,具体的赋值方式可以用户自行定义
选定了 row 和 column 之后,我们就会选择读取哪一个版本的,不同的时间戳代表着不同的数据版本.
------------------------------------------------
neo4j-图数据库
首先我们要知道neo4j是图数据库。我们平常用的数据库一般是RDBMS(关系型数据库),那么什么是图数据库呢?既然有了关系型数据库,那么为什么要有图数据库呢?
1.什么是图数据库
简单来说:
图形数据库(图形数据库也称为图形数据库管理系统或GDBMS。
图数据库的基本含义是以“图”这种数据结构存储和查询数据,而不是存储图片的数据库。它的数据模型主要是以节点和关系(边)来体现,也可处理键值对。它的优点是快速解决复杂的关系问题。
数据结构:
在一个图中主要包含两种数据类型:Nodes(节点)和Relationships(关系)。他们各自内部又包含key-value形式的属性,然后节点之间通过关系相连,形成了关系型的网状结构
图数据库的应用
金融行业应用
反欺诈多维关联分析场景
通过图分析可以清楚地知道洗钱网络及相关嫌疑,例如对用户所使用的帐号、发生交易时的IP地址、MAC地址、手机IMEI号等进行关联分析。
社交网络图谱
在社交网络中,公司、员工、技能的信息,这些都是节点,它们之间的关系和朋友之间的关系都是边,在这里面图数据库可以做一些非常复杂的公司之间关系的查询。比如说公司到员工、员工到其他公司,从中找类似的公司、相似的公司,都可以在这个系统内完成。
企业关系图谱
图数据库可以对各种企业进行信息图谱的建立,包括最基本的工商信息,包括何时注册、谁注册、注册资本、在何处办公、经营范围、高管架构。围绕企业的经营范围,继续细化去查询企业究竟有哪些产品或服务,例如通过企业名称查询到企业的自媒体,从而给予其更多关注和了解。另外也包括对企业的产品和服务的数据关联,查看该企业有没有令人信服的自主知识产权和相关资质来支撑业务的开展。
Neo4j的特点
SQL就像简单的查询语言Neo4j CQL
它遵循属性图数据模型
它通过使用Apache Lucence支持索引
它支持UNIQUE约束
它包含一个用于执行CQL命令的UI:Neo4j数据浏览器
它支持完整的ACID(原子性,一致性,隔离性和持久性)规则
它采用原生图形库与本地GPE(图形处理引擎)
它支持查询的数据导出到JSON和XLS格式
它提供了REST API,可以被任何编程语言(如Java,Spring,Scala等)访问
它提供了可以通过任何UI MVC框架(如Node JS)访问的Java脚本
它支持两种Java API:Cypher API和Native Java API来开发Java应用程序
Neo4j的优点
它很容易表示连接的数据
检索/遍历/导航更多的连接数据是非常容易和快速的
它非常容易地表示半结构化数据
Neo4j CQL查询语言命令是人性化的可读格式,非常容易学习
它使用简单而强大的数据模型
它不需要复杂的连接来检索连接的/相关的数据,因为它很容易检索它的相邻节点或关系细节没有连接或索引
Neo4j的缺点或限制
Neo4j 2.1.3最新版本,它具有支持节点数,关系和属性的限制。
它不支持Sharding。
------------------------------------------------
ClustrixDB-new数据库
ClustrixDB是一种集群式RDBMS,可确保事务处理符合ACID特性,同时可轻松的提供可扩展性和容错能力。 ClustrixDB集群由三个或更多节点(联网的同构服务器)组成。
ClustrixDB使用无共享架构。集群中的每个节点可以执行任何读取或写入操作。如果要扩充数据库容量,只需添加更多节点即可。
ClustrixDB的主要组件有助于实现性能和规模:
1) 全局事务管理器(GTM),协调给定事务的处理。
2) Rebalancer,它在集群中自动分配数据。
3) Sierra数据库引擎,确定最佳查询执行计划,然后在分布式数据节点上执行该计划。
ClustrixDB使用自动数据分发,复杂的查询计划器和分布式执行模型,以在符合ACID的RDBMS中提供可扩展性和并发性。为了实现这一点,ClustrixDB使用了许多与其他大规模并行处理(MPP)数据库使用的相同的技术:它使用Paxos进行分布式事务解析,并使用多版本并发控制(MVCC)来防止事务冲突。 借助上述主要组件,ClustrixDB为这种分布式执行提供了一个简单的SQL接口,同时还提供了可扩展性,效率和容错能力。
------------------------------------------------
SequoiaDB数据库-new数据库
随着企业中日益复杂与多变的需求,以及迅速扩展带来的海量数据的业务,IT部门需要将越来越多的信息提供给用户,同时在现今的全球经济背景环境下,IT部 门还需要在提供高效服务的同时,降低其设备与程序维护成本。SequoiaDB作为全球第一家企业级文档式非关系型数据库,则提供了诸如此类(高可扩展 性、高可用性、高性能、易维护、低成本)的全方位平台。下面从其特点、数据模型、系统架构等三个方面来了解SequoiaDB。
(一)SequoiaDB特点如下
1、当传统的关系型数据库无法做到水平扩张能力时,在SequoiaDB中会得到完美的解决,通过对数据进行垂直切片,并应用了新型的非关系型数据模型,SequoiaDB有效地降低了传统数据库分区中大量数据交换的瓶颈,进而得到线性水平扩张能力。
2、SequoiaDB能够将用户的每一份数据实时保存多份副本,有效地防止了因服务器、机房及人为等因素所造成的系统停机带来的损失,确保随时在线可用。
3、SequoiaDB为企业提供了用户友好并完善的管理、维护及监控界面,实现24×7的电话及现场技术支持,拥有完善的企业级支持。
4、SequoiaDB使用JSON数据模型,灵活有效地降低关系模型的复杂性,让数据库更加贴近应用程序,从而大大降低应用程序的开发和维护成本。
5、SequoiaDB在大规模分布式环境中提供了数据最终一致性的保障,满足用户对实时性与一致性的需求。
6、SequoiaDB通过分片机制进行读写分离,允许前端在线应用与后台数据分析完美并行互不干扰,并可结合Hadoop技术进行海量数据分析。
(二)SequoiaDB数据模型
SequoiaDB数据库没有使用传统的关系型数据模型,而是JSON数据模型。JSON数据结构的全称为Javascript Object Notation,是一种轻量级的数据交换格式,非常易于人阅读和编写,同时也易于机器生成与解析,为纯文本格式,支持嵌套结构与数组。
JSON建构基于两种结构:
1、键值对集合。在键值对集合结构中,每一个数据元素拥有一个名称与一个数值,数值可以包含数字,字符串等常用结构,或嵌套JSON对象和数组。
2、数组。在数组中的每一个元素不包含元素名,其值可以为数字、字符串等常用结构,或者嵌套JOSN对象和数组。
------------------------------------------------
------------------------------------------------
------------------------------------------------
三、架构篇
垂直切分优缺点
优点
- 解决业务系统层面的耦合,业务清晰
- 与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等
- 高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈
缺点
- 分库后无法Join,只能通过接口聚合方式解决,提升了开发的复杂度
- 分库后分布式事务处理复杂
- 依然存在单表数据量过大的问题(需要水平切分)
水平切分优缺点
优点
- 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力
- 应用端改造较小,不需要拆分业务模块
缺点
- 跨分片的事务一致性难以保证
- 跨库的Join关联查询性能较差
- 数据多次扩展难度和维护量极大
数据分片的规则,比较常见的有:Hash取模分表
、数值Range分表
、一致性Hash算法分表
。
1、Hash取模分表
概念
一般采用Hash取模的切分方式,例如:假设按goods_id分4张表。(goods_id%4 取整确定表)
优点
- 数据分片相对比较均匀,不容易出现热点和并发访问的瓶颈。
缺点
- 后期分片集群扩容时,需要迁移旧的数据很难。
- 容易面临跨分片查询的复杂问题。比如上例中,如果频繁用到的查询条件中不带goods_id时,将会导致无法定位数据库,从而需要同时向4个库发起查询,
再在内存中合并数据,取最小集返回给应用,分库反而成为拖累。
2、数值Range分表
概念
按照时间区间或ID区间来切分。例如:将goods_id为11000的记录分到第一个表,10012000的分到第二个表,以此类推。
如图
优点
- 单表大小可控
- 天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数据进行迁移
- 使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题。
缺点
- 热点数据成为性能瓶颈。
例如按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询
3、一致性Hash算法
一致性Hash算法能很好的解决因为Hash取模而产生的分片集群扩容时,需要迁移旧的数据的难题
。至于具体原理这里就不详细说,
任何事情都有两面性,分库分表也不例外,如果采用分库分表,会引入新的的问题
1、分布式事务问题
使用分布式事务中间件解决,具体是通过最终一致性还是强一致性分布式事务,看业务需求,这里就不多说。
2、跨节点关联查询 Join 问题
切分之前,我们可以通过Join来完成。而切分之后,数据可能分布在不同的节点上,此时Join带来的问题就比较麻烦了,考虑到性能,尽量避免使用Join查询。
解决这个问题的一些方法:
全局表
全局表,也可看做是 "数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库Join查询,可以将 这类表在每个数据库中都保存一份。这些数据通常
很少会进行修改,所以也不担心一致性的问题。
字段冗余
利用空间换时间,为了性能而避免join查询。例:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询"买家user表"了。
数据组装
在系统层面,分两次查询。第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。
3、跨节点分页、排序、函数问题
跨节点多库进行查询时,会出现Limit分页、Order by排序等问题。分页需要按照指定字段进行排序,当排序字段就是分片字段时,通过分片规则就比较容易定位到指定的分片;
当排序字段非分片字段时,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。
4、全局主键避重问题
如果都用主键自增
肯定不合理,如果用UUID
那么无法做到根据主键排序,所以我们可以考虑通过雪花ID
来作为数据库的主键,
有关雪花ID可以参考我之前写的博客:静态内部类单例模式实现雪花算法
5、数据迁移问题
采用双写的方式
,修改代码,所有涉及到分库分表的表的增、删、改的代码,都要对新库进行增删改。同时,再有一个数据抽取服务,不断地从老库抽数据,往新库写,
分库分表相关术语
-
读写分离: 不同的数据库,同步相同的数据,分别只负责数据的读和写;
-
分区: 指定分区列表达式,把记录拆分到不同的区域中(必须是同一服务器,可以是不同硬盘),应用看来还是同一张表,没有变化;
-
分库:一个系统的多张数据表,存储到多个数据库实例中;
-
分表: 对于一张多行(记录)多列(字段)的二维数据表,又分两种情形:
(1) 垂直分表: 竖向切分,不同分表存储不同的字段,可以把不常用或者大容量、或者不同业务的字段拆分出去;
(2) 水平分表(最复杂): 横向切分,按照特定分片算法,不同分表存储不同的记录。
规划期内的数据量和性能问题,尝试能否用下列方式解决:
-
当前数据量:如果没有达到几百万,通常无需分库分表;
-
数据量问题:增加磁盘、增加分库(不同的业务功能表,整表拆分至不同的数据库);
-
性能问题:升级CPU/内存、读写分离、优化数据库系统配置、优化数据表/索引、优化 SQL、分区、数据表的垂直切分;
-
如果仍未能奏效,才考虑最复杂的方案:数据表的水平切分。
一、垂直拆分
1、什么是垂直拆分?
指的是将一个包含了很多表的数据库,根据表的功能的不同,拆分为多个小的数据库,每个库中包含部分表。
比如:电商系统采用的库为db_eshop,根据用户功能和产品功能,可以拆分为用户库db_user和产品库db_product。
2、什么时候使用垂直拆分?
刚开始,可能公司的技术团队规模比较小,所有的数据都存放在一个库中。
随着公司业务的发展,技术团队人员扩张,划分为不同的技术小组,不同的小组负责不同的业务模块。
如:A小组负责用户模块,B小组负责产品模块。此时可以将数据库进行垂直拆分。
3、垂直拆分的好处?
垂直拆分会使得单个用户请求的响应时间变长,但是会使得整个服务的吞吐量大大的增加。(服务吞吐量即系统在单位时间内处理请求的数量)
使得单个用户请求的响应时间变长的原因在于:在单体应用场景下,所有的业务都在一个节点内部完成,而垂直拆分后,通常会需要进行rpc调用,rpc的调用会加长单个用户请求的响应时间。
4、垂直拆分的另外2种用途?
1)、将一个包含了很多字段的大表拆分为多个小表,每个表中包含部分字段(基本很少遇到)
2)、进行服务化(SOA)的改造,除了业务上需要进行拆分,底层的存储也需要进行隔离
二、读写分离
1、什么是读写分离?
将数据库分为主库和从库,一个主库用于写数据,多个从库完成读数据的操作。
主从库通过某种机制进行数据的同步。
2、为什么需要使用读写分离?
随着业务的不断发展,用户数量和并发量不断上升,此时如果仅靠单个数据库实例来支撑所有的访问压力,数据库将难以支撑。
比如:产品库中,包含了几万种产品数据,并且每天新增几十条产品数据,而产品库每天的访问可能有几亿甚至几十亿次,数据库读的压力太大,单台mysql实例扛不住。此时可以将数据库进行读写分离,主库负责数据写的操作,多个从库负责数据读的操作。
注:说白了,读写分离是为了解决数据库读的操作。
3、数据库进行了读写分离配置后,开发人员需要做哪些事情?
DBA将mysql配置成主从复制,开发人员需要做如下事情:
1)、更新数据库数据时,应用将数据写入到master主库
2)、主库将数据同步给多个slave从库
3)、当查询数据时,应用选择某一个slave节点读取数据。
4、读写分离的优点?
通过配置多个从库,可以有效的避免过大的访问量对单个库造成的压力。
5、读写分离技术所面临的问题有哪些?
读写分离的基本操作,是对sql类型进行判断,如果是select等读的请求,就走从库.
如果是insert、update、delete等写的请求,就走主库。
1)、主从数据同步延迟的问题
因为数据是从主节点通过网络同步给多个从 节点的,因此必然存在延迟问题。
因此可能出现如下问题:我们在主节点中插入了数据,但是从节点却读取不到数据的问题。
对于一些强一致性的业务场景,要求插入数据后必须能读取到,对于这种情况,我们需要提供一种方式,让读的请求也可以走主库,而主库上的数据必然是最新的。
2)、事务问题
如果一个事务中同时包含了读的请求和写的请求,如果读的请求走从库,写的请求走主库。由于跨了多个库,那么本地事务已经无法控制。
而分布式事务非常复杂且效率较低,因此读写分离,目前主流的做法是:将事务中所有sql统一走主库,由于只涉及到一个库,本地事务可以解决。
综上所述:垂直拆分可以解决服务吞吐量即提高系统在单位时间内处理请求的数量
读写分离可以缓解单库的压力,增强用户并发访问量
即经过垂直拆分和主从同步的数据库完全可以承受住难以想象的高并发访问操作。
三、水平拆分
1、什么是水平拆分(分表分库)?
通过一种算法,将数据库进行分割的架构。每个分片中的数据没有重合,所有分片中的数据并集组成全部数据。
水平分表实际又可以分为如下三种:只分表、只分库、分库分表
1)、只分表:将db库中的user表拆分为2个分表,即uer_0和user_1
2)、只分库:将db库差费为db_0和db_1这2个库,同时在db_0和db_1库中各自新建一个user表,db_0.user表和db_1.user表中各自只存放原来的db.user表中的部分数据
3)分库分表:将db库拆分为db_0和db_1这2个库,db_0中包含user_0、user_1这2个分表,db_1中包含user_2、user_3这2个分表。
2、为什么需要进行分表分库?
一旦业务表中的数据量比较大,从维护和性能的角度来看,仍然无法掩盖因为数据量过大从而导致数据库性能下降的事实。因此,这个时候mysql DBA就该对数据库进行水平分区,经过水平分区设置后的业务表,必然能够将原本一张表维护的海量数据分配给N个子表进行存储和维护。
即:单库容量最容易成为性能瓶颈,当单库容量成为瓶颈,我们希望提高数据库的写的性能,降低单库容量的话,就可以使用水平切分。
3、分表分库的使用场景?
如果库中的多个表中只有某张表或者少量表数据量过大,那么只需要针对这些表进行拆分,其它表保持不变。
4、分库分表的好处?
如果说读写分离实现数据库读能力的水平提升
那么,分库分表是是吸纳数据库写能力的水平提升
1)、存储能力的水平扩展
在读写分离的情况下,每个集群中的主从库基本上数据时完全一致的,从存储能力上讲
在存储海量数据的情况下,可能由于磁盘空间的限制,无法存储所有的数据。
而分库分表的情况下,我们可以搭建多个mysql主从复制集群,每个集群只存储部分分片的额数据,实现了存储能力的水平扩展。
2)、写能力的水平扩展
在读写分离的情况下,由于每个集群只有一个master,所有的写操作的压力都集中在这一个节点上,在写入并发非常高的情况下,这将会成为整个系统的瓶颈。
而在分表分库的情况下,每个分片所属的集群都有一个master节点,都可以执行写入的操作,实现写能力的水平扩展,此外减小建立索引开销,降低写操作的锁操作耗时等,都会带来很多显著的好处。
5、分库分表的问题
主要体现在如下4个方面:基本数据的增删改功能、分布式id、分布式事务、动态扩容
1)、基本的数据库增删改功能
对于开发人员而言,虽然分库分表的,但是其还是希望能和单库单表那样去操作数据库。
如:我们要批量插入4条记录,并且希望根据用户的id字段,确定这条记录插入哪个库的那张表中。如:1号记录插入user1表….4号记录插入user4表
那么之前的单库作如下:
insert into user(id,name) values (1,”tianshouzhi”),(2,”huhuamin”), (3,”wanghanao”),(4,”luyang”)
这显然无法实现,因为我们已经对库和表进行了拆分,这种sql语法只能操作mysql的单个库和单个表,所以必须将sql改为4条,然后分表到每个库上去执行,如下:
insert into user0(id,name) values (4,”luyang”)
insert into user1(id,name) values (1,”tianshouzhi”)
insert into user2(id,name) values (2,”huhuamin”)
insert into user3(id,name) values (3,”wanghanao”)
2)、分布式id
在分库分表后,我们不能再使用mysql的自增主键。
因为在插入记录的时候,不同的库生成的记录的自增id可能会出现冲突
因此,需要一个全局的id生成器,目前分布式id有很多种方案,其中一个比较轻量级的方案是twitter的snowflake算法。
3)、分布式事务
分布式事务是分库分表的绕不过去的一个坎,因为涉及到了同时更新多个分片数据。
如:批量插入记录到四个不同的库,如何保证要么同时成功,要么同时失败。
关于分布式事务,mysql支持XA事务,但是效率较低。
柔性事务是目前比较主流的方案,柔性事务包括:最大努力通知型、可靠消息最终一致性方案以及TCC两个阶段提交。
但是无论XA事务还是柔性事务,实现起来都是非常复杂的。
4)、动态扩容
动态扩容是指只增加分库分表的数量
如:将原来user表拆分到2个库的四张表上。
现在我们希望将分库的数量变为4个,分表的数量变为8个。
这种情况一般要伴随着数据迁移,如在4张表的情况下,id为7的记录,7%4=3
因此这条记录位于user3这张表上,但是现在分表的数量变为8个,而7%8=0
而user0这张表根本没有id=7这条记录,因此如果不进行数据迁移的话,就会出现记录找不到的情况。
数据切分
1、垂直(纵向)切分
垂直切分的优点:
- 解决业务系统层面的耦合,业务清晰
- 与微服务的治理类似,也能对不同业务的数据进行分级管理、维护、监控、扩展等
- 高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈
缺点:
- 部分表无法join,只能通过接口聚合方式解决,提升了开发的复杂度
- 分布式事务处理复杂
- 依然存在单表数据量过大的问题(需要水平切分)
2、水平(横向)切分
水平切分的优点:
- 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力
- 应用端改造较小,不需要拆分业务模块
缺点:
- 跨分片的事务一致性难以保证
- 跨库的join关联查询性能较差
- 数据多次扩展难度和维护量极大
几种典型的数据分片规则为:
1、根据数值范围
2、根据数值取模
二. 分库分表带来的问题
1、事务一致性问题
分布式事务
当更新内容同时分布在不同库中,不可避免会带来跨库事务问题。跨分片事务也是分布式事务,没有简单的方案,一般可使用"XA协议"和"两阶段提交"处理。
分布式事务能最大限度保证了数据库操作的原子性。但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间。导致事务在访问共享资源时发生冲突或死锁的概率增高。随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平扩展的枷锁。
最终一致性
对于那些性能要求很高,但对一致性要求不高的系统,往往不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,可采用事务补偿的方式。与事务在执行中发生错误后立即回滚的方式不同,事务补偿是一种事后检查补救的措施,一些常见的实现方法有:对数据进行对账检查,基于日志进行对比,定期同标准数据来源进行同步等等。事务补偿还要结合业务系统来考虑。
2、跨节点关联查询 join 问题
切分之前,系统中很多列表和详情页所需的数据可以通过sql join来完成。而切分之后,数据可能分布在不同的节点上,此时join带来的问题就比较麻烦了,考虑到性能,尽量避免使用join查询。
解决这个问题的一些方法:
1)全局表
全局表,也可看做是"数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库join查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。
2)字段冗余
一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。例如:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询"买家user表"了。
但这种方法适用场景也有限,比较适用于依赖字段比较少的情况。而冗余字段的数据一致性也较难保证,就像上面订单表的例子,买家修改了userName后,是否需要在历史订单中同步更新呢?这也要结合实际业务场景进行考虑。
3)数据组装
在系统层面,分两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。
4)ER分片
关系型数据库中,如果可以先确定表之间的关联关系,并将那些存在关联关系的表记录存放在同一个分片上,那么就能较好的避免跨分片join问题。在1:1或1:n的情况下,通常按照主表的ID主键切分。
3、跨节点分页、排序、函数问题
4、全局主键避重问题
5、数据迁移、扩容问题
三. 什么时候考虑切分
下面讲述一下什么时候需要考虑做数据切分。
1、能不切分尽量不要切分
并不是所有表都需要进行切分,主要还是看数据的增长速度。切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好的实现需求也是其重要工作之一。
不到万不得已不用轻易使用分库分表这个大招,避免"过度设计"和"过早优化"。分库分表之前,不要为分而分,先尽力去做力所能及的事情,例如:升级硬件、升级网络、读写分离、索引优化等等。当数据量达到单表的瓶颈时候,再考虑分库分表。
2、数据量过大,正常运维影响业务访问
这里说的运维,指:
1)对数据库备份,如果单表太大,备份时需要大量的磁盘IO和网络IO。例如1T的数据,网络传输占50MB时候,需要20000秒才能传输完毕,整个过程的风险都是比较高的
2)对一个很大的表进行DDL修改时,MySQL会锁住全表,这个时间会很长,这段时间业务不能访问此表,影响很大。如果使用pt-online-schema-change,使用过程中会创建触发器和影子表,也需要很长的时间。在此操作过程中,都算为风险时间。将数据表拆分,总量减少,有助于降低这个风险。
3)大表会经常访问与更新,就更有可能出现锁等待。将数据切分,用空间换时间,变相降低访问压力
3、随着业务发展,需要对某些字段垂直拆分
举个例子,假如项目一开始设计的用户表如下:
id bigint #用户的ID
name varchar #用户的名字
last_login_time datetime #最近登录时间
personal_info text #私人信息
..... #其他信息字段
在项目初始阶段,这种设计是满足简单的业务需求的,也方便快速迭代开发。而当业务快速发展时,用户量从10w激增到10亿,用户非常的活跃,每次登录会更新 last_login_name 字段,使得 user 表被不断update,压力很大。而其他字段:id, name, personal_info 是不变的或很少更新的,此时在业务角度,就要将 last_login_time 拆分出去,新建一个 user_time 表。
personal_info 属性是更新和查询频率较低的,并且text字段占据了太多的空间。这时候,就要对此垂直拆分出 user_ext 表了。
4、数据量快速增长
随着业务的快速发展,单表中的数据量会持续增长,当性能接近瓶颈时,就需要考虑水平切分,做分库分表了。此时一定要选择合适的切分规则,提前预估好数据容量
5、安全性和可用性
鸡蛋不要放在一个篮子里。在业务层面上垂直切分,将不相关的业务的数据库分隔,因为每个业务的数据量、访问量都不同,不能因为一个业务把数据库搞挂而牵连到其他业务。利用水平切分,当一个数据库出现问题时,不会影响到100%的用户,每个库只承担业务的一部分数据,这样整体的可用性就能提高。
----------------------
2 全局ID生成策略
2.1 自动增长列
优点:数据库自带功能,有序,性能佳。
缺点:单库单表无妨,分库分表时如果没有规划,ID可能重复。解决方案:
2.1.1 设置自增偏移和步长
-
### 假设总共有 10 个分表
-
### 级别可选: SESSION(会话级), GLOBAL(全局)
-
SET @@SESSION.auto_increment_offset = 1; ### 起始值, 分别取值为 1~10
-
SET @@SESSION.auto_increment_increment = 10; ### 步长增量
如果采用该方案,在扩容时需要迁移已有数据至新的所属分片。
2.1.2 全局ID映射表
在全局 Redis 中为每张数据表创建一个 ID 的键,记录该表当前最大 ID;
每次申请 ID 时,都自增 1 并返回给应用;
Redis 要定期持久至全局数据库。
2.2 UUID(128位)
在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成UUID的API。
UUID 由4个连字号(-)将32个字节长的字符串分隔后生成的字符串,总共36个字节长。形如:550e8400-e29b-41d4-a716-446655440000。
UUID 的计算因子包括:以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。
UUID 是个标准,其实现有几种,最常用的是微软的 GUID(Globals Unique Identifiers)。
优点:简单,全球唯一;
缺点:存储和传输空间大,无序,性能欠佳。
2.3 COMB(组合)
参考资料:The Cost of GUIDs as Primary Keys
组合 GUID(10字节) 和时间(6字节),达到有序的效果,提高索引性能。
2.4 Snowflake(雪花) 算法
参考资料:twitter/snowflake,Snowflake 算法详解
Snowflake 是 Twitter 开源的分布式 ID 生成算法,其结果为 long(64bit) 的数值。
其特性是各节点无需协调、按时间大致有序、且整个集群各节点单不重复。
该数值的默认组成如下(符号位之外的三部分允许个性化调整):
-
1bit: 符号位,总是 0(为了保证数值是正数)。
-
41bit: 毫秒数(可用 69 年);
-
10bit: 节点ID(5bit数据中心 + 5bit节点ID,支持 32 * 32 = 1024 个节点)
-
12bit: 流水号(每个节点每毫秒内支持 4096 个 ID,相当于 409万的 QPS,相同时间内如 ID 遇翻转,则等待至下一毫秒)
3 分片策略
3.1 连续分片
根据特定字段(比如用户ID、订单时间)的范围,值在该区间的,划分到特定节点。
优点:集群扩容后,指定新的范围落在新节点即可,无需进行数据迁移。
缺点:如果按时间划分,数据热点分布不均(历史数冷当前数据热),导致节点负荷不均。
3.3 ID取模分片
缺点:扩容后需要迁移数据。
3.2 一致性Hash算法
优点:扩容后无需迁移数据。
3.4 Snowflake 分片
优点:扩容后无需迁移数据。
4 分库分表引入的问题
4.1 分布式事务
参见 分布式事务的解决方案
由于两阶段/三阶段提交对性能损耗大,可改用事务补偿机制。
4.2 跨节点 JOIN
对于单库 JOIN,MySQL 原生就支持;
对于多库,出于性能考虑,不建议使用 MySQL 自带的 JOIN,可以用以下方案避免跨节点 JOIN:
-
全局表: 一些稳定的共用数据表,在各个数据库中都保存一份;
-
字段冗余: 一些常用的共用字段,在各个数据表中都保存一份;
-
应用组装:应用获取数据后再组装。
另外,某个 ID 的用户信息在哪个节点,他的关联数据(比如订单)也在哪个节点,可以避免分布式查询。
4.3 跨节点聚合
只能在应用程序端完成。
但对于分页查询,每次大量聚合后再分页,性能欠佳。
4.4 节点扩容
节点扩容后,新的分片规则导致数据所属分片有变,因而需要迁移数据。
5 节点扩容方案
相关资料: 数据库秒级平滑扩容架构方案
5.1 常规方案
如果增加的节点数和扩容操作没有规划,那么绝大部分数据所属的分片都有变化,需要在分片间迁移:
-
预估迁移耗时,发布停服公告;
-
停服(用户无法使用服务),使用事先准备的迁移脚本,进行数据迁移;
-
修改为新的分片规则;
-
启动服务器。
5.2 免迁移扩容
采用双倍扩容策略,避免数据迁移。扩容前每个节点的数据,有一半要迁移至一个新增节点中,对应关系比较简单。
具体操作如下(假设已有 2 个节点 A/B,要双倍扩容至 A/A2/B/B2 这 4 个节点):
-
无需停止应用服务器;
-
新增两个数据库 A2/B2 作为从库,设置主从同步关系为:A=>A2、B=>B2,直至主从数据同步完毕(早期数据可手工同步);
-
调整分片规则并使之生效:
原ID%2=0 => A
改为ID%4=0 => A, ID%4=2 => A2
;
原ID%2=1 => B
改为ID%4=1 => B, ID%4=3 => B2
。 -
解除数据库实例的主从同步关系,并使之生效;
-
此时,四个节点的数据都已完整,只是有冗余(多存了和自己配对的节点的那部分数据),择机清除即可(过后随时进行,不影响业务)。
6 分库分表方案
6.1 代理层方式
部署一台代理服务器伪装成 MySQL 服务器,代理服务器负责与真实 MySQL 节点的对接,应用程序只和代理服务器对接。对应用程序是透明的。
比如 MyCAT,官网,源码,参考文档:MyCAT+MySQL 读写分离部署
MyCAT 后端可以支持 MySQL, SQL Server, Oracle, DB2, PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。
MyCAT 不仅仅可以用作读写分离,以及分表分库、容灾管理,而且可以用于多租户应用开发、云平台基础设施,让你的架构具备很强的适应性和灵活性。
6.2 应用层方式
处于业务层和 JDBC 层中间,是以 JAR 包方式提供给应用调用,对代码有侵入性。主要方案有:
(1)淘宝网的 TDDL: 已于 2012 年关闭了维护通道,建议不要使用。
(2)当当网的 Sharding-JDBC: 仍在活跃维护中:
是当当应用框架 ddframe 中,从关系型数据库模块 dd-rdb 中分离出来的数据库水平分片框架,实现透明化数据库分库分表访问,实现了 Snowflake 分片算法;
Sharding-JDBC定位为轻量Java框架,使用客户端直连数据库,无需额外部署,无其他依赖,DBA也无需改变原有的运维方式。
Sharding-JDBC分片策略灵活,可支持等号、between、in等多维度分片,也可支持多分片键。
SQL解析功能完善,支持聚合、分组、排序、limit、or等查询,并支持Binding Table以及笛卡尔积表查询。
Sharding-JDBC直接封装JDBC API,可以理解为增强版的JDBC驱动,旧代码迁移成本几乎为零:
-
可适用于任何基于Java的ORM框架,如JPA、Hibernate、Mybatis、Spring JDBC Template或直接使用JDBC。
-
可基于任何第三方的数据库连接池,如DBCP、C3P0、 BoneCP、Druid等。
-
理论上可支持任意实现JDBC规范的数据库。虽然目前仅支持MySQL,但已有支持Oracle、SQLServer等数据库的计划。
分布式数据层中间件
分布式数据访问层中间件,旨在为供一个通用数据访问层服务,支持MySQL动态数据源、读写分离、分布式唯一主键生成器、分库分表、动态化配置等功能,并且支持从客户端角度对数据源的各方面(比如连接池、SQL等)进行监控,后续考虑支持NoSQL、Cache等多种数据源。
2.作用
- 动态数据源
- 读写分离
- 分布式唯一主键生成器
- 分库分表
- 连接池及SQL监控
- 动态化配置等
常见的数据层中间件

1.TDDL
淘宝根据自己的业务特点开发了TDDL框架,主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的JDBC datasource实现。
特点
实现动态数据源、读写分离、分库分表。
缺点
分库分表功能还未开源,当前公布文档较少,并且需要依赖diamond(淘宝内部使用的一个管理持久配置的系统)
2.DRDS
阿里分布式关系型数据库服务(Distribute Relational Database Service,简称DRDS)是一种水平拆分、可平滑扩缩容、读写分离的在线分布式数据库服务。
前身为淘宝 TDDL,下一代是 DRDS,整合云服务,收费、Cobar、TDDL整合,商用,首选。
2.Atlas
Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。
它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。
主要功能:
1.读写分离
2.从库负载均衡
3.IP过滤
4.自动分表
5.DBA可平滑上下线DB
6.自动摘除宕机的DB
3.MTDDL(Meituan Distributed Data Layer)
美团点评分布式数据访问层中间件
特点
实现动态数据源、读写分离、分库分表,与tddl类似。
下面我以MTDDL为例,也可以参考淘宝tddl,完整详解分布式数据层中间件的架构设计。
分库分表数据库中间件对比
(一)关键问题
1.读写分离
2.分库分表
3.类别
- lib库
1)业务直接到数据库,少一层proxy效率更高
2)没有proxy的lvs的单点问题
- proxy
1)统一管理所有到数据库的连接,连接复用
2)基础查询功能抽象,减少代码耦合
3)易于实现监控、数据迁移、连接管理等功能
(二)sharding-jdbc(开源,lib)
当当应用框架ddframe中,从关系型数据库模块dd-rdb中分离出来的数据库水平分片框架
- 功能
1)以jar包形式提供服务
2)分片灵活,支持等号、between、in等多维度分片
3)sql解析,支持聚合、分组、排序、limit、or等
- 结构
- 特点
1)分片规则:策略自定义、复数分片数
2)JDBC规范重写:针对DataSource、Connection、Statement、PreparedStatement和ResultSet接口封装
3)sql解析:druid
4)sql改写:修改逻辑表名->真实表名;替换不支持的功能,如:avg->sum和count
5)sql路由:单表路由、binding表路由、笛卡尔积路由
6)sql执行:多线程并发执行sql
7)结果归并:遍历类、排序类(归并排序)、聚合类(比较型、累加型、平均型)、分组类
(三)mycat(开源,proxy)
社区爱好者在阿里cobar基础上进行二次开发,解决了cobar的一些问题,且加入了新的功能。
- 功能
1)遵守mysql原生协议
2)基于心跳的自动故障切换
3)支持读写分离,支持mysql主从
4)支持sum、count、max等聚合,支持跨库分页
5)支持服务降级
6)安全,IP白名单、sql注入攻击拦截、prepare预编译
- 原理
拦截:分片分析、路由分析、读写分离分析、缓存分析
(四)DBproxy(开源,proxy)
针对atlas进行改进,形成了新的高可靠、高可用企业级数据库中间件DBProxy
- 功能
1)读写分离
2)负载均衡
3)slave故障感知&摘除
4)连接池
5)自定义sql拦截&过滤
6)流量分组&控制
7)监控状态
(五)atlas
360团队基于mysql proxy把lua用c改写,在高并发下经常会挂掉。
(六)oneproxy(不开源,proxy)
基于mysql协议的数据库中间件。利用c进行开发的,专注于性能和稳定性。
- 功能
透明sql路由(实现后端mysql数据库的集群化部署)和流量分析(为上层应用和底层数据库集群提供丰富的性能监控功能)。
1)复用数据库连接,降低数据库并发连接数
2)即时发现和剔除不可用的后端节点,转发应用请求实现高效故障隔离
3)内置守护进程模式和ha vip机制,确保高可用
4)查询语句分离,跨分片结果集合并,根据分片并行执行sql
5)读写分离
6)对sql语句进行安全检查,拒绝危险的DDL操作
7)分别设置前端应用和后端数据库的sql请求频率,实现QoS控制
8)实时透明分析流量,实时统计sql和事务的运行时间,分析事务的sql结构
- 特点
语言:C&C++开发
网络事件:libevent框架
内存分配:jemalloc优化
QPS:单实例支持40W
连接池:透明连接池的功能,具备mysqk企业版连接池效果
主备:实现透明的读写分离路由
安全:sql请求类别;请求IP;每个sql请求实时检查&拦截
流量分析:IP维度、事务维度展示&分析
稳定:内置高可用、也可与zookeeper等配合
(七)vitess
Youtube上产使用的,架构复杂
--------------------------------------------
四、工具篇
1、Sharding-JDBC 简介
最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现已更名为 ShardingSphere
,2020年416正式成为 Apache
软件基会的顶级项。
随着版本的不断更迭 的核心功能也变得多元化起来。从最开始 Sharding-JDBC 1.0 版本只有数据分片,到 Sharding-JDBC 2.0 版本开始支持数据库治理(注册中心、配置中心等等),再到 Sharding-JDBC 3.0版本又加分布式事务 (支持 Atomikos
、Narayana
、Bitronix
、Seata
),如今已经迭代到了 Sharding-JDBC 4.0 版本。
现在的 ShardingSphere 不单单是指某个框架而是一个生态圈,这个生态圈 、Sharding-Proxy
和 Sharding-Sidecar
这三款开源的分布式数据库中间件解决方案所构成。
的前身就是 ,所以它是整个框架中最为经典、成熟的组件,我们先从 框架入手学习分库分表。
二、核心概念
在开始 分库分表具体实战之前,我们有必要先了解分库分表的一些核心概念。
分片
一般我们在提到分库分表的时候,大多是以水平切分模式(水平分库、分表)为基础来说的,数据分片将原本一张数据量较大的表 t_order
拆分生成数个表结构完全一致的小数据量表 t_order_0
、t_order_1
、···、t_order_n
,每张表只存储原大表中的一部分数据,当执行一条SQL
时会通过 分库策略
、分片策略
将数据分散到不同的数据库、表内。
数据节点
数据节点是分库分表中一个不可再分的最小数据单元(表),它由数据源名称和数据表组成,例如上图中 order_db_1.t_order_0
、order_db_2.t_order_1
就表示一个数据节点。
逻辑表
逻辑表是指一组具有相同逻辑和数据结构表的总称。比如我们将订单表 拆分成 ··· t_order_9
真实表
真实表也就是上边提到的 数据库中真实存在的物理表。
分片键
用于分片的数据库字段。我们将 表分片以后,当执行一条SQL时,通过对字段 order_id
取模的方式来决定,这条数据该在哪个数据库中的哪个表中执行,此时 字段就是 表的分片健。
这样以来同一个订单的相关数据就会存在同一个数据库表中,大幅提升数据检索的性能,不仅如此 sharding-jdbc
还支持根据多个字段作为分片健进行分片。
分片算法
上边我们提到可以用分片健取模的规则分片,但这只是比较简单的一种,在实际开发中我们还希望用 >=
、<=
、>
、<
、BETWEEN
和 IN
等条件作为分片规则,自定义分片逻辑,这时就需要用到分片策略与分片算法。
从执行 SQL 的角度来看,分库分表可以看作是一种路由机制,把 SQL 语句路由到我们期望的数据库或数据表中并获取数据,分片算法可以理解成一种路由规则。
咱们先捋一下它们之间的关系,分片策略只是抽象出的概念,它是由分片算法和分片健组合而成,分片算法做具体的数据分片逻辑。
分库、分表的分片策略配置是相对独立的,可以各自使用不同的策略与算法,每种策略中可以是多个分片算法的组合,每个分片算法可以对多个分片健做逻辑判断。
注意:sharding-jdbc 并没有直接提供分片算法的实现,需要开发者根据业务自行实现。
提供了4种分片算法:
1、精确分片算法
精确分片算法(PreciseShardingAlgorithm)用于单个字段作为分片键,SQL中有 =
与 等条件的分片,需要在标准分片策略(StandardShardingStrategy
)下使用。
2、范围分片算法
范围分片算法(RangeShardingAlgorithm)用于单个字段作为分片键,SQL中有 BETWEEN AND
、、、、 )下使用。
3、复合分片算法
复合分片算法(ComplexKeysShardingAlgorithm)用于多个字段作为分片键的分片操作,同时获取到多个分片健的值,根据多个字段处理业务逻辑。需要在复合分片策略(ComplexShardingStrategy
)下使用
4、Hint分片算法
Hint分片算法(HintShardingAlgorithm)稍有不同,上边的算法中我们都是解析 语句提取分片键,并设置分片策略进行分片。但有些时候我们并没有使用任何的分片键和分片策略,可还想将 SQL 路由到目标数据库和表,就需要通过手动干预指定SQL的目标数据库和表信息,这也叫强制路由。
分片策略
上边讲分片算法的时候已经说过,分片策略是一种抽象的概念,实际分片操作的是由分片算法和分片健来完成的。
1、标准分片策略
标准分片策略适用于单分片键,此策略支持 PreciseShardingAlgorithm
和 RangeShardingAlgorithm
两个分片算法。
其中 是必选的,用于处理 和 的分片。 是可选的,用于处理, , ,, 条件分片,如果不配置,SQL中的条件等将按照全库路由处理。
2、复合分片策略
复合分片策略,同样支持对 SQL语句中的 ,, , , ,和 的分片操作。不同的是它支持多分片键,具体分配片细节完全由应用开发者实现。
3、行表达式分片策略
行表达式分片策略,支持对 SQL语句中的 和 的分片操作,但只支持单分片键。这种策略通常用于简单的分片,不需要自定义分片算法,可以直接在配置文件中接着写规则。
t_order_$->{t_order_id % 4}
代表 对其字段 t_order_id
取模,拆分成4张表,而表名分别是 到 t_order_3
。
4、Hint分片策略
Hint分片策略,对应上边的Hint分片算法,通过指定分片健而非从 中提取分片健的方式进行分片的策略。
分布式主键
数据分后,不同数据节点成全局唯主键是常棘的问题,同个逻辑表()内的不同真实表()之间的增键由于法互相感知而产重复主键。
尽管可通过设置增主键 初始值
和 步
的式避免ID碰撞,但这样会使维护成本加大,乏完整性和可扩展性。如果后去需要增加分片表的数量,要逐一修改分片表的步长,运维成本非常高,所以不建议这种方式。
实现分布式主键成器的方式很多,具体可以百度,网上有很多
为了让上手更加简单,ApacheShardingSphere 内置了UUID
、SNOWFLAKE
两种分布式主键成器,默认使雪花算法(snowflake
)成64bit的整型数据。不仅如此它还抽离出分布式主键成器的接口,便我们实现定义的增主键成算法。
广播表
广播表:存在于所有的分片数据源中的表,表结构和表中的数据在每个数据库中均完全一致。一般是为字典表或者配置表 t_config
,某个表一旦被配置为广播表,只要修改某个数据库的广播表,所有数据源中广播表的数据都会跟着同步。
绑定表
绑定表:那些分片规则一致的主表和子表。比如: 订单表和 t_order_item
订单服务项目表,都是按 字段分片,因此两张表互为绑定表关系。
那绑定表存在的意义是啥呢?
通常在我们的业务中都会使用 和 等表进行多表联合查询,但由于分库分表以后这些表被拆分成N多个子表。如果不配置绑定表关系,会出现笛卡尔积关联查询,将产生如下四条。
SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id
2、ShardingSphere概念
1、概念
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar这3款相互独立的产品组成。
他们均提供标准化的数据分片
、分布式事务
和 数据库治理功能
,可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。
如图
2、功能列表
数据分片
- 分库 & 分表
- 读写分离
- 分片策略定制化
- 无中心化分布式主键
分布式事务
- 标准化事务接口
- XA强一致事务
- 柔性事务
数据库治理
- 配置动态化
- 编排 & 治理
- 数据脱敏
- 可视化链路追踪
- 弹性伸缩(规划中)
3、项目状态
2、Maxwell 简介
-
Maxwell 是一个能实时读取 MySQL 二进制日志文件binlog,并生成 Json格式的消息,作为生产者发送给 Kafka,Kinesis、RabbitMQ、Redis、
Google Cloud Pub/Sub、文件或其它平台的应用程序。它的常见应用场景有ETL、维护缓存、收集表级别的dml指标、增量到搜索引擎、数据分区迁移、
切库binlog回滚方案等。 -
Maxwell主要提供了下列功能
- 支持SELECT * FROM table的方式进行全量数据初始化。
- 支持在主库发生failover后,自动恢复binlog位置,实现断点续传。
- 可以对数据进行分区,解决数据倾斜问题,发送到Kafka的数据支持库、表、列等级别的数据分区。
- 工作方式是伪装为slave接收binlog events,然后根据schema信息拼装,可以接受ddl、xid、row等event。
2、Mysql Binlog介绍
2.1 Binlog 简介
-
MySQL中一般有以下几种日志
日志类型 写入日志的信息 错误日志 记录在启动,运行或停止mysqld时遇到的问题 通用查询日志 记录建立的客户端连接和执行的语句 二进制日志 binlog 记录更改数据的语句 中继日志 从服务器 复制 主服务器接收的数据更改 慢查询日志 记录所有执行时间超过 long_query_time
秒的所有查询或不使用索引的查询DDL日志(元数据日志) 元数据操作由DDL语句执行 -
在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的,但是在一般稍微重要一点的实际应用场景中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件
-
接下来主要介绍二进制日志 binlog。
- MySQL 的二进制日志 binlog 可以说是 MySQL 最重要的日志,它记录了所有的
DDL
和DML
语句(除了数据查询语句select、show等),以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。binlog 的主要目的是复制和恢复。
- MySQL 的二进制日志 binlog 可以说是 MySQL 最重要的日志,它记录了所有的
-
Binlog日志的两个最重要的使用场景
- MySQL主从复制
- MySQL Replication在Master端开启binlog,Master把它的二进制日志传递给slaves来达到master-slave数据一致的目的。
- 数据恢复
- 通过使用 mysqlbinlog工具来使恢复数据。
- MySQL主从复制
2.2 Binlog 的日志格式
-
记录在二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:
- Statement:基于SQL语句的复制(statement-based replication, SBR)
- Row:基于行的复制(row-based replication, RBR)
- Mixed:混合模式复制(mixed-based replication, MBR)
-
Statement
- 每一条会修改数据的sql都会记录在binlog中。
- 优点
- 不需要记录每一行的变化,减少了binlog日志量,节约了IO, 提高了性能。
- 缺点
- 在进行数据同步的过程中有可能出现数据不一致。
- 比如 update tt set create_date=now(),如果用binlog日志进行恢复,由于执行时间不同可能产生的数据就不同。
-
Row
- 它不记录sql语句上下文相关信息,仅保存哪条记录被修改。
- 优点
- 保持数据的绝对一致性。因为不管sql是什么,引用了什么函数,它只记录执行后的效果。
- 缺点
- 每行数据的修改都会记录,最明显的就是update语句,导致更新多少条数据就会产生多少事件,占用较大空间。
-
Mixed
- 从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
- 在Mixed模式下,一般的复制使用Statement模式保存binlog,对于Statement模式无法复制的操作使用Row模式保存binlog, MySQL会根据执行的SQL语句选择日志保存方式(因为statement只有sql,没有数据,无法获取原始的变更日志,所以一般建议为Row模式)。
- 优点
- 节省空间,同时兼顾了一定的一致性。
- 缺点
- 还有些极个别情况依旧会造成不一致,另外statement和mixed对于需要对binlog的监控的情况都不方便。
3、Mysql 实时数据同步方案对比
-
mysql 数据实时同步可以通过解析mysql的 binlog 的方式来实现,解析binlog可以有多种方式,可以通过canal,或者maxwell等各种方式实现。以下是各种抽取方式的对比介绍。
-
其中
canal
由 Java开发,分为服务端和客户端,拥有众多的衍生应用,性能稳定,功能强大;canal 需要自己编写客户端来消费canal解析到的数据。 -
Maxwell相对于canal的优势是使用简单,Maxwell比Canal更加轻量级,它直接将数据变更输出为json字符串,不需要再编写客户端。对于缺乏基础建设,短时间内需要快速迭代的项目和公司比较合适。
-
另外
Maxwell
有一个亮点功能,就是Canal只能抓取最新数据,对已存在的历史数据没有办法处理。而Maxwell有一个bootstrap
功能,可以直接引导出完整的历史数据用于初始化,非常好用。
3、Sqoop概述
Sqoop是一个旨在Hadoop和关系数据库或主机之间传输数据的工具。你可以使用Sqoop从关系型数据库管理系统(RDBMS),如MySQL、Oracle或大型机到Hadoop分布式文件系统(HDFS)导入数据,在Hadoop中的MapReduce转换数据,然后将数据导出到一个RDBMS 。Sqoop使用MapReduce导入和导出数据,它提供了并行操作,以及容错。
MySQL
将驱动对应的jar包放置到 /usr/share/java/下。
如:/usr/share/java/mysql-connector-java-5.1.32-bin.jar
<span id="4"></span>
4.1.1 保护密码
在sqoop命令中显式指定密码会是很不安全的操作,使用操作系统的列出正在执行的命令的方式可以很容易的获取到密码。有两种方式可以解决这个问题。
方式一:使用-P(大写)参数,在执行命令时再输入密码。
方式二:使用--password-file参数,即将密码存放在参数指定的文件中。
<span id="412"></span>
4.1.2 使用其他文件格式
Sqoop支持3中不同的文件格式,其中一种是文本格式,两外两种是二进制格式。二进制格式分别是Avro和SequenceFile。使用--as-avrodatafile或--as-sequencefile以指定具体使用哪种二进制格式。
<span id="413"></span>
4.1.3 压缩导入的数据
使用—compress或-z参数以压缩导入之后的数据。默认的压缩算法为GZip,所有文件的后缀名均为.gz。可以使用—compress-codec来指定其他的codec。如
--compression-codec org.apache.hadoop.io.compress.BZip2Codec
使用压缩需要将mapreduce中对应的设置项开启,如mapreduce.output.
compress。
<span id="414"></span>
4.1.4 提高传输速度
不同于JDBC接口,direct模式下使用数据库提供的本地工具进行数据传输。在MySQL中使用mysqldump和mysqlimport。对于PostgreSQL,sqoop会使用pg_dump工具来导入数据。使用本地工具会极大提高性能,因为他们针对数据传输做了优化,以降低数据库服务器的负担。当然也有很多限制,比如并不是所有的数据库都提供本地工具。目前sqoop的direct模式只支持MySQL和PostgreSQL。
<span id="415"></span>
4.1.5 自定义类型映射
使用—amp-column-java参数来将列列映射到java类以覆盖sqoop提供的默认的映射关系。
如要将c1、c2、c3分别映射为Float、String、String,对应的设置如下所示。
sqoop import --map-column-java c1=Float,c2=String,c3=String ...
<span id="416"></span>
4.1.6 并行控制
Sqoop默认使用4个并发的map任务来项hadoop传输数据。当数据量比较大时可以考虑增加并发执行的map任务的数量以提高传输速度。使用参数—num-mappers来控制map任务的数量。
<span id="417"></span>
4.1.7 对NULL值进行编码
Sqoop使用“null”字符串来代替数据库中的NULL值。对于文本类型的列,使用—null-string来设置替代NULL值得字符串,对于其他类型的列,则使用—null-non-string来设置。
如果想使用\N来编码NULL值,则对应sqoop命令中的值为\N, \在JAVA中是转义字符。
4、使用binlog+canal或binlake进行数据库的复制
1.Binlog
mysql有多种日志,常见的有:
错误日志(ErrorLog)
更新日志(UpdateLog)
二进制日志(Binlog)
查询日志(QueryLog)
慢查询日志(SlowQueryLog)
Binlog可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,此外Binlog是事务安全型的。
Binlog一般作用是可以用于实时备份,与master/slave主从复制结合。
2.Canal
Canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的。
Canal作为阿里巴巴提供的开源的数据抽取项目,能够做到实时抽取,原理就是伪装成mysql从节点,读取mysql的binlog,生成消息,客户端订阅这些数据变更消息,处理并存储
github : https://github.com/alibaba/canal
3.Binlake
BinLake坚持技术和资源共享的原则,为京东商城各个业务部门提供统一的资源和技术服务,各个业务部门通过使用BinLake服务,避免的重复投入人力对同一项技术进行研究,避免了各个部门为了满足同一种业务需求而重复申请资源,进而避免的资源浪费,避免的各个业务部门重复投入人力和物力进行数据库日志采集、管理、分发、订阅系统的运维。
Binlake架构图:
1.BinLake总共包括三大服务组件:
1.1 Wave服务
Wave服务完成实际的数据库Binary Log的持续采集、管理和分发写入到下游的消息发布和订阅系统中。在BinLake集群中会存在N个Wave服务,这些Wave服务共同组成一个无状态集群。
1.2 Tower服务
Tower服务是整个BinLake的管理中心,提供BinLake接入服务的申请、完成Wave服务、数据源、接入应用的管理。当用户申请接入到BinLake中时,会登录到Tower服务提供的申请界面,填写申请接入BinLake的应用信息、数据源信息和Topic信息,Tower服务会按照用户提供的信息做如下判断,并完成用户接入申请,接入流程如下:
如果不同申请者申请相同数据源的数据采集,由Tower管理端依据其申请的采集规则(如指定表,指定库),如果规则相同,默认复用相同规则的Topic,也可强制生成新的Topic进行订阅。
1.3 Judge服务
Judge服务主要完成两个功能:Wave节点监控信息采集和loadBalance决策。
Wave节点监控信息采集:
通过在各个Wave服务节点部署agent采集各个Wave服务节点上的监控信息,包括:服务器的内存使用、系统负载、CPU负载、网络负载、JVM的堆内存使用、GC信息、每个Wave服务中的instance个数等,采集到的所有这些信息都会在后续的loadBalance中作为基础metics,参与到最终的loadBalance决策中。
loadBalance决策:
新应用接入到BinLake时,若需要采集的数据源在BinLake现有的数据源池中不存在,则需要针对于新的数据源在相应的Wave服务上创建对应的instance(数据源与instance是1对1的关系)。那么在创建instance的时候,就需要选在在哪个Wave服务上创建。这时就会请求Judge服务提供的loadBalance决策接口,若Judge服务中没有配置loadBalance plugin,则会返回一个随机的Wave服务节点的IP,那么就会在该随机的Wave服务上创建instance;若配置了loadBalance的plugin,则从Judge服务提供的loadBalance决策接口获得建议Wave服务节点,并从该节点创建新的instance。
2.BinLake依赖于两大外部服务:
2.1 ZooKeeper
BinLake使用zookeeper服务进行Wave无状态集群的管理、状态同步和消息通知等,包括:
【1】Instance的自动化创建与初始化
【2】Instance的HA
【3】数据源offset实时追踪
【4】binlog分发失败重试
【5】数据源切换自适配
【6】Tower元数据管理
【7】instance消息通知
2.2 消息发布与订阅系统
目前BinLake可以无缝集成JMQ和Kafka,从而进行消息的发布和订阅管理。instance采集到的BinLog Event会发布到JMQ或者Kafka的Topic中,实际的业务应用只需要订阅和消费对应的topic,既可以实时的获得BinLog Event,并在后续的业务逻辑中对获得的Binlog Event进行处理即可。
5、
--------------------------------------------
--------------------------------------------
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
2021-02-08 cpa-审计