1 数据库的读写分离
1.1 Amoeba实现读写分离
1.1.1 定义
Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy
优点:
- 配置读写分离时较为简单.配置文件编写方便
- 可以做到整个数据库的读写分离
- 占用的资源较少.
缺点:
- 不能实现高可用
- 现在不更新维护了
1.2 搭建amoeba
1.2.1 安装JDK
说明:Amoeba的使用依赖于JDK.
1.2.2 安装Amoeba
说明:将Amoeba文件拖入/usr/local/src/
将其解压
1.2.3 使用工具修改xml
通过工具连接远程的amoeba虚拟机
1.3 修改DBServer.xml
1.3.1 修改用户名和密码
1.3.2 配置数据库服务
说明:定义主数据库的IP地址
1.3.3 定义读操作策略
1.4 Amoeba配置
1.4.1 修改Amoeba.xml文件
说明:
默认的amoeba访问主库.
如果配置了读写分离则采用读写分离的操作数据库
所有的写库操作访问主数据库.
所有的读操作,访问multiPool负载均衡后的数据库slave,master,salve
Amoeba默认的访问端口是8066
1.5 修改JVM内存
1.5.1 修改内存
说明:
说明:原因的jvm配置文件大小只有256M太小,amoeba不能正常启动,需要修改JVM大小.
1.6 Amoeba启动
1.6.1 启动Amoeba
说明:进入到bin目录下执行启动命令
/usr/local/src/amoeba-mysql-3.0.4-BETA/bin
./launcher 启动
./shutdown 停止
1.7 Amoeba测试
1.7.1 连接Amoeba
说明:通过工具连接远程Amoeba.切记关闭防火墙
1.7.2 代码测试
说明:通过京淘后台管理修改数据源配置,通过代码测试Amoeba
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.126.139:8066/jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.username=root
jdbc.password=root
1.8 错误集锦
1.8.1 关闭主库和从库的防火墙
说明:当虚拟机开机后,防火墙默认开启了,需要再次手动关闭.
1.8.2 修改配置文件后没有及时报错
共修改2个配置文件dbServer.xml,amoeba.xml
需要通过工具进行下载和上传/保证上传的文件不错.
1.8.3 报错端口占用
- 关机重启
- 查询项目的进程后杀死进程
Kill -9 5652
- ./shutdown 关闭amoeba
- 修改JVM内存
2 Mycat介绍
2.1 Mycat下载
2.1.1 下载地址
官网地址: http://www.mycat.io/
2.1.2 安装JDK
2.2 MyCat安装
2.2.1 解压文件
tar -xvf Mycat………
2.2.2 编辑schemas.xml文件
2.2.3 定义负载策略:
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<!--配置第一台主机主要进行写库操作,在默认的条件下Mycat主要操作第一台主机
在第一台主机中已经实现了读写分离.
因为默认写操作会发往137的数据库.
读的操作默认发往141.如果从节点比较忙,则主节点分担部分压力.
-->
<writeHost host="hostM1" url="192.168.126.137:3306" user="root" password="root">
<!--读数据库-->
<readHost host="hostS1" url="192.168.126.141:3306" user="root" password="root" />
</writeHost>
<!--定义第二台主机 由于数据库内部已经实现了双机热备.
Mycat实现高可用.当第一个主机137宕机后.mycat会自动发出心跳检测.检测3次.如果主机137没有给Mycat响应则判断主机死亡.则启动第二台主机继续为用户提供服务.
如果137主机恢复之后则处于等待状态.如果141宕机则137再次持续为用户提供服务.
前提:实现双机热备.
-->
<writeHost host="hostM2" url="192.168.126.141:3306" user="root" password="root">
<readHost host="hostS1" url="192.168.126.137:3306" user="root" password="root" />
</writeHost>
</dataHost>
2.2.4 修改server.xml
默认的schemas是TextDB.需要手动修改
2.2.5 启动Mycat
说明:进入根目录cd /usr/local/src/bin
./mycat start 启动
./mycat stop关闭mycat
2.2.6 测试
2.3 报错说明
2.3.1 IP错误
检测IP地址和自己的机器是否匹配
192.168.126.137
2.3.2 配置文件上传是否正确
- 分别检测server.xml和schema文件是否上传成功
2.如果正确还是测试不成功,则先关闭mycat,控制台通过rm -rf 命令将Mycat的2个配置文件删除.之后通过FZ工具上传修改后的配置文件.之后重启mycat
2.3.3 检测日志是否启动成功
cd /usr/local/src/mycat/logs/ cat wrapper.log
2.3.4 关于getByte报错
由于Mycat中解析配置文件时会出现报错信息,
所以将每行注释都添加<!—注释-->
3 Redis学习
3.1 传统框架中的瓶颈
3.1.1 缓存机制
缓存机制其实就是降低了客户端访问真实数据源的访问频次.缓存中的数据就是数据源就数据的备份.如果数据源数据发生改变.缓存数据需要及时更新.
3.1.2 缓存中遇到的问题
- 如果采用单台缓存服务器,很容器出现宕机现象.如果缓存服务器宕机将直接影响整个服务.---解决方案部署缓存集群
- 如果实现缓存则需要实现数据的同步—配置主从
- 如果缓存服务器宕机.数据如何保存.应该将数据尽可能持久化
3.1.3 Redis内存数据库
说明:redis现阶段所有企业中使用最多的内存数据库.其中主要采用key-value的形式保存数据.并且提供很多实用的数据类型.String/list/set/hash.
Redis底层通过C编辑,可以每秒支持110000次的集合运算.并且在内存中运行.
Redis底层实现时自动支持数据的持久化.如果reids重启会自动的扫描持久化文件之后恢复数据.
3.1.4 Redis的下载
Window版本不建议使用
因为官方没有提供window版本,该window版本是微软自己研发.稳定性不强
3.1.5 缓存架构
3.1.6 解压redis
tar -xvf redis-3.2.8.tar.gz
3.1.7 编译redis
在根目录下执行 /usr/local/src/redis-3.2.8 执行make指令
make
生成可执行文件
3.1.8 安装redis
make install
4 Redis操作
4.1 启动redis
4.1.1 直接启动
命令:redis-server
说明:默认端口都是6379
问题:通过redis-server启动时,之后不能编写linux命令,需要再次创建链接.造成编码不便
4.1.2 后台启动
- 解除IP绑定
- 关闭保护模式
- 开启后台运行
- 开启后台redis
redis-server redis.conf
ps -ef |grep redis
root 5847 1 0 01:45 ? 00:00:00 redis-server *:6379
root 5852 2571 0 01:45 pts/1 00:00:00 grep redis
4.2 操作redis
4.2.1 进入客户端
执行命令:redis-cli
4.3 Redis的操作命令
4.3.1 String 类型操作
| 指令 | 说明 | 案例 | 
| set | 设定key的值 | set name tom | 
| get | 获取指定 key 的值 | get name | 
| strlen | 获取key值的长度 | strlen name | 
| exists | 检查给定 key 是否存在 | exists name 返回1存在 0不存在 | 
| del | 删除指定的key/key1 key2 | del name1 name2 | 
| keys | 命令用于查找所有符合给定模式 pattern 的 key | Keys * 查询全部的key值 Keys n?me 占位符 Keys name* 以name开头的key | 
| mset | 赋值多个key-value | mset key1 value1 key2 value2 key3 value3 同时赋值多个值 | 
| mget | 获取多个key | Mget key1 key2 key3 | 
| append | 对指定的key进行追加 | append key 123456 value123456 append key " 123456" value 123456中间多一个空格 | 
| Type | 查看key的类型 | Type key1 127.0.0.1:6379> TYPE key1string | 
| Flushdb | 清空当前数据库 | Flushdb 清空数据库 | 
| Select | 切换数据库 | Select 0-15 redis一共有16个数据库 | 
| FLUSHALL | 清空全部数据库数据 | flushall | 
| Incr | 自动增长1 | Incr num 数据会自动加1 Incr string 数据库会报错 | 
| Decr | 自动减1 | Decr name 数据会自动减1 | 
| incrby | 指定步长自增 | Incrby 2 每次自增2 | 
| Decrby | 指定步长自减 | Decrby 2每次减2 | 
| Expire | 指定key的失效时间单位是秒(s) | EXPIRE name1 5 5秒后数据失效 | 
| Ttl | 查看key的剩余存活时间 | Ttl name -2表示失效 -1没有失效时间 | 
| Pexpire | 设置失效时间(毫秒) | Pexpire name 1000 用于秒杀业务 | 
| Persist | 撤销失效时间 | 撤销失效时间 | 
| 指令 | 说明 | 案例 | 
| hset | Hset key值 属性名 属性值 | Hset user id 1 Hset user name tom 设置id和name的属性值 | 
| hget | 获取指定 key的属性值 | Hget user name 获取name属性值 | 
| hmset | Hmset user key value1 key2 value2 | hmset user id 1 name tom age 18 | 
| hmget | hmget user id name age | hmget user id name age 获取user对象的id,name,age的属性值 | 
| hgetall | 取出key的全部字段值和属性值 | HGETALL user 
 
 | 
| hdel | 删除key的指定字段 | 删除key的指定字段 
 
 | 
| Hkeys | 查看key的全部字段 | HKEYS user | 
| hvals | 查看key的全部值 | Hvals user 
 
 | 
| hlen | 查看key的字段数 | Hlen user 查看user的字段数 | 
4.3.2 Redis集合数据类型
1.字符串类型 String
2.散列类型 hash
3.列表类型 list
4.集合类型 set
5.有序集合类型
1.散列类型
可以通过散列类型用来保存对象和属性的值
例如:user对象 {id:2,name:小明,age:19}
通过散列类型赋值不需要{}
4.3.3 List列表类型
List列表类型(list)是一个存储有序的元素的集合类型.List数据类型底层是一个双端列表.可以从左右分别进行写入操作
| 指令 | 说明 | 案例 | 
| lpush | 将一个或多个值插入到列表左部插入 | LPUSH list1 1 2 3 4 | 
| rpush | 在列表中添加一个或多个从列表右侧插入 | RPUSH list1 5 6 7 8 | 
| lpop | 从列表左侧移除元素,并且返回结果 | LPOP list1 | 
| rpop | 从列表右侧移除元素,并且返回结果 | RPOP list1 | 
| llen | 获取list集合的元素个数 | Llen list1 | 
| Lrange | 获取指定区间内的片段值 | LRANGE list1 0 3 获取从左数第1个到第4个值 LRANGE list1 -3 -1 从右数第三个到第一个数据 Lrange list1 0 -1 查询全部列表数据 
 
 | 
| Lrem | 删除列表中指定的值 Irem key count value 当count>0,从左开始删除前count个值为value的元素 当count<0,从右侧开始删除前count个值为value的元素 当count=0时,删除所有value的元素 | LREM list1 2 2 从左数前2个为2的元素 LREM list1 -2 3 从右数前2个为3的元素 LREM list1 0 4 删除全部为4的元素 | 
| Lindex | 根据指定索引值查询元素 | LINDEX list1 0 查找索引值为0的值 LINDEX list1 -1 查询最右边的值 | 
| Lset | 为指定索引赋值 | LSET list1 0 10 | 
| LINSERT | LINSERT key before value1 value2 在value1之前插入value2 LINSERT list1 after 1 2 
 | LINSERT list1 before 10 100 从左数第一个为10的元素前插入100 LINSERT list1 after 1 2 从左数第一个为1的值之后插入2 | 
双端列表的数据特点:查询两端数据时速度较快,查询中间数据较慢.
4.3.4 redis集合类型
redis支持集合类型,并且每个集合的元素类型都可以不同,并且集合时无序的.
| 指令 | 说明 | 案例 | 
| sadd | 向集合添加一个或多个成员 | sadd set a b c | 
| scard | 获取集合的成员数 | SCARD set | 
| srem | 删除集合的指定元素 | SREM set a 删除set中的a元素 | 
| smembers | 查看集合的所有元素 | SMEMBERS set | 
| Sismember | 查看元素是否属于集合 | SISMEMBER set a 查看a是否属于set集合 | 
| sdiff | 返回给定所有集合的差集 | 
 
 | 
| sinter | 返回给定所有集合的交集 | 
 
 | 
| sunion | 返回所有给定集合的并集 | A={1,2,3} B={2,3,4} SUNION a b = 1,2,3,4 
 
 | 
