文档首页/ 分布式缓存服务 DCS/ 最佳实践/ 业务应用/ 使用DCS改造传统应用系统数据库
更新时间:2024-10-24 GMT+08:00

使用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

      同一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包)。

    本文档下载的开发工具和客户端仅为示例,您可以选择其它类型的工具和客户端。

实施步骤

  1. 登录MySQL数据库所在服务器。
  2. 在MySQL数据库所在服务器安装Redis客户端用来进行数据的提取、传输和转换。安装Redis客户端请参考安装Redis客户端
  3. 分析源端数据结构,在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

  4. 在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表中的记录数相同,则整表迁移成功。

  5. 迁移完成后,一条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。