分布式数据存储
海量数据的存储问题
- 如今随着互联网的发展,数据的量级也是成指数的增长 从GB到TB到PB
- 对数据的各种操作也是愈加的困难,
传统的关系型数据库
已经无法满足快速查询与插入数据的需求。 - 这个时候NoSQL的出现
暂时解决了这一危机
它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。 但是,在有些场合NoSQL一些折衷是无法满足使用场景的,就比如 有些使用场景是绝对要有事务与安全指标的 这个时候NoSQL肯定是无法满足的,所以还是需要使用关系性数据库 - 如果使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群
- 为了提高查询性能将一个数据库的数据,分散到不同的数据库中存储。
数据切分
什么是数据库分片
- 简单来说,就是指通过某种特定的条件
- 将我们存放在同一个数据库中的数据分散存放到多个数据库主机上,以达到分散单台设备负载的效果。
- 三种分片模式
垂直切分
- 垂直切分是根据
业务维度来拆分数据库
- 同一个应用程序下 用户模块 对应用户数据库的开发… 订单模块 对应订单数据库的开发…
- 两个不相互,影响却是
运行于一个项目开发
水平切分
- 水平切分是按照某个字段的某种规则,
从数据维度 进行数据的拆分
- 将一个海量的数据库,表中数据,
根据某种规则, 分发到 多个
相同结构的数据表中! 注意! 拆分的数据库/表,结构必须一样,不然还怎么分发…
混合切分
- 实际开发中常见! 就是将
垂直模式 水平模式
两种模块的混合就是 混合模式切分 - 从业务维度 和 数据维度的结合,对海量数据进行的拆分操作…
数据库中间件:Mycat
简介
- Mycat 背后是阿里曾经开源的知名产品——
Cobar
Cobar 的核心功能和优势是 MySQL 数据库分片,此产品曾经广为流传。 - Mycat 是基于 cobar 演变而来,对 cobar 的代码进行了彻底的重构
- 使用 NIO 重构了网络模块,并且优化了 Buffer 内核,增强了聚合,Join 等基本特性, 同时兼容绝大多数数据库成为通用的数据库中间件。 Mysql Oracle SQLServer…
总结:
- MyCAT就是: 一个数据库中间件产品支持mysql集群,
- 因为Mycat 开发团队就是Mysql的开发团队,都是一家的…两者兼容性极高!
- 你可以像使用mysql一样使用mycat。对于开发人员来说根本感觉不到mycat的存在。
Mycat
概念说明:
逻辑库:schema
- 逻辑库是数据库集群对外的统一访问入口, 程序先连接到逻辑库上,再由逻辑库进行分配
- 实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念 所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。
逻辑表:table
- 应用读写数据的表是逻辑表,是由一个或多个物理表组成
逻辑表上记录着
多个数据节点分片!
通过向逻辑表读写操作, 而操作多个数据节点分片!
数据节点:dataNode
- 数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点(dataNode)
数据主机:dataHost
- 数据节点所在的主机
就是
数据主机 - 即:具体物理数据所在的
数据库地址!
Mysql / Oracle 具体数据库的地址… - 多个数据节点,可以是不同的数据主机…在不同的ip地址下…数据库集群…
分片规则:rule
- 一个大表被分成若干个分片表,就需要一定的规则
- 这样按照某种业务规则把数据分到某个分片的规则就是分片规则, 数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。
Mycat 环境搭建:
安装环境
- 要求jdk必须是1.7及以上版本
- 推荐mysql是5.5以上版本
- Mycat的官方网站:
安装步骤
- Mycat有windows、linux多种版本。
本人Windows 为主!
- Mycat 基本是解压即用的…
- 管理员cmd: bin目录下启动Mycat:
mycat.bat start
- Mycat的默认端口号为:
8066
- 停止:
mycat.bat stop
注意:
在windows上安装mycat执行命令时
- cmd控制台 wrapper | OpenSCManager failed - 拒绝访问。 (0x5)解决
- 这是因为当前用户权限不够,
运行cmd时以管理员身份运行即可
搭建java环境
- conf 目录下,wrapper.conf文件修改对应的java jdk对应的目录
例如:
wrapper.java.command=G:java_jdkjdkbinjava.exe
提示你需要安装运行环境:
- cmd管理员运行:
mycat.bat install
Mycat 配置文件:
- rule 设置分片规则
- schema 设置分片逻辑库信息…
- server 设置 Mycat 用户/密码
本人这里截取本人的一些片段了解…
rule.xml
- 配置分片规则!
<!--tableRule 配置一个表分片规则!
name 分片规则名!
-->
<tableRule name="mod-long">
<!-- 根据id列进行规则分配! -->
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm> <!-- 引用下面Mycat提供的分配规则...官方提供的很多不一一列举了! -->
</rule>
</tableRule>
<!-- Mycat分片规则算法! -->
<function name="murmur"
class="org.opencloudb.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 默认是0 -->
<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
<property name="virtualBucketTimes">160</property><!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍 -->
<!-- <property name="weightMapFile">weightMapFile</property> 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
</function>
<!-- 本人采用的取模,轮询算法;
根据id 值取模 3;
id 取模值 结果
1 % 3 1 第二个库
2 % 3 2 第三各库
3 % 3 0 第一个库
...........
-->
<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
schema.xml
代码语言:javascript复制 <!--
schema 声明一个逻辑库
name 逻辑库名称
checkSQLschema 检查sql中有没有schema存在。true(schema.表)
sqlMaxLimit
查询逻辑表中的sql中是否使用limit关键字
如果使用的sql没有指定limit指定会加一条limit,避免海量数据的查询。
如果物理表没有切分库的话,上面的参数就不会起作用。
-->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!--
table 声明一个逻辑库: 用于声明数据分片...是 schema的子元素,可以存在多个table
name 逻辑表名称:对应要查询的物理库上的表!
dataNode 指定一个/n个数据节点
rule 分片规则,引用 rule.xml 中定义的分片规则,具体根据那个类,进行什么样的规则进行分片处理!
-->
<table name="WSM" dataNode="dn1,dn2,dn3" rule="mod-long" />
</schema>
<!--
dataNode 配置数据节点
name 节点名
dataHose 指定节点主机,下面声明的!
database 数据库中的库!
-->
<dataNode name="dn1" dataHost="localhost1" database="wsm-mycat1" />
<dataNode name="dn2" dataHost="localhost1" database="wsm-mycat2" />
<dataNode name="dn3" dataHost="localhost1" database="wsm-mycat3" />
<!--
dataHost
一个datahost是一组服务器,构建一个集群环境,对于集群环境会涉及到主/从关系。
对于mysql服务上有1个写入服务器,和多台读取服务器。
主从关系,和读写分离:
主写,从读: 因为读取是经常发生的事情,而写入的操作相对来说并不是很多! 大部分时候是查询的操作要多!
一般主服务器为writeHost,从服务器为readHost
balance 指的负载均衡类型,目前的取值有4种:
balance=“0” 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上
balance=“1” 全部的readHost与闲置 writeHost参与select语句的负载均衡...
balance=“2” 所有读操作都随机的在writeHost、readhost上分发。
balance=“3” 所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
switchType 指的是切换的模式,目前的取值也有3种
switchType=‘-1’ 表示不自动切换
switchType=‘1’ 表示自动切换
switchType=‘2’ 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status
writeType (写服务器可以有多台)指定执行哪一台写服务器
slaveThreshold
主从备份,数据同步的时间间隔
当有两台服务器,都进行读操作, 程序会根据它们上一次读取的时间,分析性能,时间短的性能高, 优先进行读操作!
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!--
host 主机名
url 主机地址
user 用户名
password 密码
-->
<writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="ok">
<!-- 集群环境的配置... -->
<!-- <readHost host="hostS1" url="127.0.0.1:3306" user="root" password="ok"> -->
</writeHost>
</dataHost>
server.xml
- 配置了Mycat 的用户信息!
<!--
name 登录的用户名
property name="password" 密码!
property name="schemas" 操作的逻辑库!对应schema.xml文件!
-->
<user name="test">
<property name="password">test</property>
<property name="schemas">TESTDB</property>
</user>
运行测试:
- 创建三个 Mysql 物理库: 各存在一个 wsm表
三个表结构都要一样!
- mycat
schema.xml文件进行管理:
- 在Mycat 上查询…自动根据
schema.xml文件
映射查询到Mysql 对应库上的 表! - Mycat连续新增三条记录:
- 三个记录,根据
mod-long
分片规则进行了,轮询有序的 取模拆分到三个数据库中去!
- 忽略我的数据,中间出来点意味,数据有点不符合…