使用DCS改造传统应用系统数据库
方案概述
应用场景
随着互联网等数据库应用行业的逐渐发展,业务需求急速增加,数据量和并发访问量呈指数级增长,仅依附于传统关系型数据库难以支撑上层业务。传统数据库存在结构复杂、维护成本高、访问性能差、功能有限、无法轻松适应数据模型或模式的变化等问题。
解决方案
将Redis作为应用与数据库之间的缓存层可以解决上述问题,通过Redis缓存数据,提高数据读取速度,减轻数据库负载,提高应用性能,保证数据的可靠性。
因此,对于传统的关系型数据库例如MySQL,可以将其数据迁移到Redis中。Redis中的数据是以键值结构进行存储的,在迁移前需要将传统的数据库转换为特定的结构。本文以将MySQL数据库中的一张表迁移到华为云DCS Redis中为例,介绍数据迁移的过程。
前提条件
- 已创建DCS Redis实例,作为迁移的目的数据库。请参考创建DCS Redis缓存实例。
如果您的源端是华为云的MySQL数据库,Redis实例请选择与MySQL数据库实例相同的VPC。
- 已有MySQL数据库,并在其中创建一张表,作为源端数据库中的数据。
例如,在MySQL数据库中创建一张名为student_info的表格,表中共有4列,迁移后表中的id列的值将成为Redis中的hash的key,其余的列名将成为hash的field,而列的值作为field对应的value。
- MySQL数据库所在服务器与DCS缓存实例网络互通。
- MySQL数据库与Redis实例所在VPC为同一VPC
- MySQL数据库与Redis实例所在VPC为相同region下的不同VPC
如果MySQL数据库所在VPC与Redis实例不在相同VPC中,可以通过建立VPC对等连接方式连通网络,具体请参考:缓存实例是否支持跨VPC访问?。
- MySQL数据库与Redis实例所在VPC不在相同region
如果MySQL数据库和Redis实例不在同一region,仅支持通过云专线打通网络,请参考云专线。
- 公网访问
MySQL数据库所在服务器公网访问Redis 4.0/5.0/6.0实例请参考使用Nginx实现公网访问DCS或使用华为云ELB公网访问DCS。
- MySQL数据库所在服务器已安装JDK1.8以上版本和Intellij IDEA开发工具,下载jedis客户端(点此处下载jar包)。
本文档下载的开发工具和客户端仅为示例,您可以选择其它类型的工具和客户端。
实施步骤
- 登录MySQL数据库所在服务器。
- 在MySQL数据库所在服务器安装Redis客户端用来进行数据的提取、传输和转换。安装Redis客户端请参考安装Redis客户端。
- 分析源端数据结构,在MySQL数据库所在服务器中创建如下的迁移脚本,保存文件名为migrate.sql。
SELECT CONCAT( "*8\r\n", #这里的8是下方字段的数量,由MySQL表中的数据结构决定 '$', LENGTH('HMSET'), '\r\n', #HMSET是在Redis中写入数据时使用的命令 'HMSET', '\r\n', '$', LENGTH(id), '\r\n', #id是HMSET字段后的第一个字段,迁移后会成为Redis Hash中的key id, '\r\n', '$', LENGTH('name'), '\r\n', #'name'将以字符串形式传入hash中,作为其中一个field。下面的'birthday'等与它相同 'name', '\r\n', '$', LENGTH(name), '\r\n', #name是一个变量,代表了MySQL表中公司的名称,迁移后会成为上一参数'name'生成的field所对应的value。下面的birthday等与它相同 name, '\r\n', '$', LENGTH(' birthday'), '\r\n', ' birthday', '\r\n', '$', LENGTH(birthday), '\r\n', birthday, '\r\n', '$', LENGTH('city'), '\r\n', 'city', '\r\n', '$', LENGTH(city), '\r\n', city, '\r' ) FROM student_info AS s
- 在MySQL数据库所在服务器中使用如下命令迁移数据。
mysql -h <MySQL host> -P <MySQL port> -u <MySQL username> -D <MySQL database name> -p --skip-column-names --raw < migrate.sql | redis-cli -h <Redis host> -p<Redis port> --pipe -a <Redis password>
表1 参数项说明 参数项
说明
示例
-h
MySQl数据库的连接地址。
xxxxxx
-P
MySQL的服务端口。
3306
-u
MySQL的用户名。
root
-D
待迁移的表所在的库。
mysql
-p
MySQL的连接密码。如果没有密码,-p后为空。
为了提高安全性,可以只输入-p,不在其后输入密码,执行命令后再根据命令行提示输入密码。
xxxxxx
--skip-column-names
不在查询结果中写入列名。
无需设置
--raw
输出列的值时不进行转义。
无需设置
Redis-cli之后的-h
Redis的连接地址。
redis-xxxxxxxxxxxx.com
Redis-cli 后的-p
Redis的端口。
6379
--pipe
使用Redis的Pipeline功能进行传输。
无需设置
-a
Redis的连接密码。如果没有密码则不需设置。
xxxxxx
上图中以Redis实例没有设置密码为例,执行结果中的errors表示执行过程中的错误数,replies表示收到的回复数。如果errors为0,且replies与MySQL表中的记录数相同,则整表迁移成功。
- 迁移完成后,一条MySQL数据对应一条Redis的Hash数据。可以连接Redis后用HGETALL命令查询验证。结果如下:
[root@ecs-cmtest mysql-8.0]# redis-cli -h redis-xxxxxxxxxxxx.com -p 6379 redis-xxxxxxxxxxxx.com:6379> HGETALL 1 1) "name" 2) "Wilin" 3) " birthday" 4) "1995-06-12" 5) "city" 6) "Nanjing" redis-xxxxxxxxxxxx.com:6379> HGETALL 4 1) "name" 2) "Anbei" 3) " birthday" 4) "1969-10-19" 5) "city" 6) "Dongjing"
也可以根据实际场景中需要的查询方式调整迁移方案。例如把MySQL数据中的其他列转换为hash中的key,把id列转换为field。