
# Pika到GeminiDB Redis的迁移
Pika是一个可持久化的大容量Redis存储服务，解决了Redis由于存储数据量巨大而导致内存不够用的容量瓶颈。但其集群管理功能较为薄弱，需要使用twemproxy或者codis实现静态数据分片。同时由于数据全部存储在磁盘中，相比于社区版Redis，性能明显下降。
GeminiDB Redis接口是一款兼容Redis生态的云原生NoSQL数据库，基于共享存储池的多副本强一致机制，保证数据的安全可靠。GeminiDB Redis接口实现了冷热分离，解决了缓存（cache）与数据库（Data Base，DB）之间交互访问的问题，提高了程序可读性与程序运行效率。同时对RocksDB进行深度定制，实现秒级分裂弹性扩容，扩缩容无需搬迁数据，快速而平滑。通过proxy代理，使上层业务可以不感知内核处理扩缩容过程中的数据迁移。
本章节主要介绍Pika到GeminiDB Redis接口的迁移方案。
#### 迁移原理
pika-port伪装成Pika的从节点运行，通过主从复制的方式进行数据迁移。Pika主节点通过比较pika-port和自己的binlog偏移量判断做全量迁移还是增量迁移。如果需要做全量迁移，Pika主节点会将全量数据快照发送给pika-port，pika-port将解析后的快照数据发送给GeminiDB Redis。全量迁移结束后进入增量迁移，pika-port将增量数据解析后以redis命令的形式发送给GeminiDB Redis。
图1迁移原理   
![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001747263569.png "点击放大")
Pika-migrate的迁移原理和pika-port相似，将工具虚拟为pika的从库，然后从主库获取到数据转发给目标redis，同时支持增量同步，实现在线热迁的功能。
pika-migrate 通过 dbsync 请求获取主库全量 DB 数据，以及当前 DB 数据所对应的 binlog 点位。获取到主库当前全量 DB 数据之后，扫描 DB，将 DB 中的数据打包转发给 Redis。通过之前获取的 binlog 的点位向主库进行增量同步, 在增量同步的过程中，将从主库获取到的 binlog 重组成redis命令，转发给redis。
#### 适用版本
Pika到Redis迁移工具Pika-Port适用于Pika v2.x和v3.0.x版本，具体使用步骤请参考[pika-port迁移工具使用说明]或者[pika到pika、redis迁移工具](https://github.com/OpenAtomFoundation/pika/wiki/pika到pika、redis迁移工具)。如果使用Pika v3.2及以上版本，需使用迁移工具Pika-Migrate，具体步骤请参考[pika-migrate迁移工具使用说明]。
#### 使用须知
- Pika迁移工具伪装成源端Pika的从节点，只读取全量和增量数据，无数据受损风险。
- 源端增加了和Pika迁移工具的主从同步流程，可能会影响源端性能。
- 全量和增量结合迁移可以不停服，业务切入GeminiDB Redis时短暂停服。
 
 #### pika-port迁移工具使用说明
- 部署迁移工具pika-port
  - 迁移工具下载 从Github上直接下载编译好的对应pika版本的pika-port开源迁移工具（如pika3.0.x版本就使用3.0.x版本的开源工具），网址为：<https://github.com/ipixiu/pika-port-bin>。
    图2迁移工具下载   
    ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001749358885.png "点击放大") 
  
  - 部署位置和目录结构 以pika_portv1.6.0为例，将解压后的整个文件重命名为pika_port3，复制在部署了pika的环境上（或者任一能与pika实例和GeminiDB Redis实例网络互通的服务器上），解压后的pika_port3文件夹目录结构如下：
    ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001701479350.png)
    
  
  - 迁移前准备 由于sbin目录下的pika-port二进制文件需要引用lib目录下的库文件，迁移之前需在pika_port3路径执行如下命令：
    export LD_LIBRARY_PATH=./lib:${LD_LIBRARY_PATH} //链接库文件
    rm -rf ./rsync_dump/ //删除文件夹
    rm -rf ./sync_log/ //删除sync日志
    
   
- pika单机数据迁移
  - 启动命令 执行如下命令，启动pika_port迁移工具：
    ./sbin/pika_port -i master_ip -o master_port -m forward_ip -n forward_port -x forward_thread_num -y forward_passwd -f filenum -s offset -w password -r rsync_dump_path -l log_path
    -h -- show this help
    -t -- local host ip(OPTIONAL default: 127.0.0.1)，输入本机IP
    -p -- local port(OPTIONAL)，默认即可
    -i -- Pika主节点IP
    -o -- Pika主节点port
    -m -- GeminiDB Redis ELB IP
    -n -- GeminiDB Redis port
    -x -- 发送线程数量(OPTIONAL default: 1)
    -y -- GeminiDB Redis密码
    -f -- binlog文件数量，默认即可(OPTIONAL default: local offset)
    -s -- binlog offset，默认即可(OPTIONAL default: local offset)
    -w -- Pika主节点密码
    -r -- rsync dump文件到本地目录，默认即可(OPTIONAL default: ./rsync_dump)
    -l -- 产生的日志文件目录，默认即可(OPTIONAL default: ./log)
    -b -- max batch number when port rsync dump data. 默认即可 (OPTIONAL default: 512)
    -d -- 是否后台运行(OPTIONAL)
    示例：
    ./sbin/pika_port -t 28.80.60.200 -p 12345 -i 28.80.60.200 -o 9221 -m 28.80.60.201 -n 6379 -x 7 -y a -w a
    【注】上例中，28.80.60.200为源端pika IP，28.80.60.201为目标端redis IP。
    
  
  - 等待结果 等待数据迁移，若执行日志中出现如下信息，代表全量数据同步完成，此后数据迁移进入增量同步阶段。
    ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001701638886.png "点击放大")
    
   
- pika集群数据迁移 迁移步骤同pika单机数据迁移步骤，为每个pika实例创建一个工作流即可。
  
 
 #### pika-migrate迁移工具使用说明
- 迁移工具部署
  - Pika-migrate工具下载：<https://github.com/OpenAtomFoundation/pika/tree/v3_2_7_migrate>
  
  - 工具使用说明：<https://github.com/OpenAtomFoundation/pika/blob/v3_2_7_migrate/pika-migrate.md>
  
  - 也可以直接使用编译好的二进制文件。 将解压后的整个pika_migrate_output文件放置在部署了pika的环境上（或者任一能与pika实例和GeminiDB Redis实例网络互通的服务器上），解压后的文件夹目录结构如下：
    ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001749478689.png)
    使用前清空db、dbsync和log目录下的内容。
    
   
- 迁移步骤
  1. 修改配置文件 根据目标端(redis)的信息，修改迁移工具的配置文件conf/pika.conf 中的如下参数:
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001749358889.png)
     target-redis-host：Redis 的 IP 地址。
     target-redis-port：Redis 的端口号。
     target-redis-pwd：Redis 默认账号的密码。
     masterauth：Pika主库的密码（如Pika主库没有设置密码则不填）。
     ![](https://support.huaweicloud.com/redisug-nosql/public_sys-resources/caution_3.0-zh-cn.png)
     - binlog文件为log/log_db0目录下记录了所有操作的同步日志文件，这部分文件在增量同步数据阶段使用
     
     - 将全量数据写入到Redis这段时间可能耗时很长，而导致Pika主库原先的binlog文件被清理。需要在Pika主库上保留足够的binlog⽂件个数，确保后续该⼯具请求增量同步的时候，对应的binlog文件还存在。
     
     - binlog文件占用磁盘空间，可以根据观察Pika主库实际生成该文件的情况确定保留binlog的数量。
       
  
  2. 在pika主库上执行"**config set expire-logs-nums 10000** "命令，让 PIKA 主库保留10000个 binlog 文件。
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001701479354.png "点击放大")
     
  
  3. 在工具包的路径下执行如下命令，启动 pika-migrate 工具，并查看控制台回显信息: bin/pika -c conf/pika.conf。 ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001712446558.png "点击放大")
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001760245961.png "点击放大")
     
  
  4. 在pika-migrate客户端执行如下命令，将迁移工具伪装成 Slave，向主库请求同步，并观察控制台是否打印报错信息。 **slaveof \[pika** **主库ip\] \[pika** **主库port\]**
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001749358893.png)
     如果主从关系建立，此时回显信息为：
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001701479358.png "点击放大")
     
  
  5. 确认主从关系建立成功之后，pika-migrate开始向目标端Redis转发数据。在pika主库和从库执行"info Replication"命令，查看主从同步延迟。可在主库写入一个特殊的 key，然后在 Redis 侧查看是否可立即获取到该 key，判断数据同步完毕。 ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001701638894.png "点击放大")
     ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001749478697.png "点击放大")
     
   
- 注意事项
  - pika-migrate在线迁移只支持单DB场景，不支持多DB场景。
  
  - pika-migrate在线迁移不支持集群模式：严格来说，pika进程有两种模式启动，一种是classic，一种是sharding，其中sharding模式不支持pika-migrate迁移。 具体模式可以在pika.conf里进行查看：
    ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001731720502.png "点击放大")
    
   

- 常见问题
  - 如果从库一直未收到主库响应，会一直停留在Need To Sync阶段： ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001778801481.png "点击放大")
    
  
  - 可能原因
    - pika主库未使用root启动导致rsync无权限，请参考网址：https://github.com/OpenAtomFoundation/pika/issues/553。
    
    - rsync使用端口未开启监听，请开启监听。
    
    - rsync使用端口已被其他进程占用，请解除端口占用。 ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000001731721462.png "点击放大")
      
     
   
 
#### 迁移后Redis数据一致性校验
迁移完成后，您可以对Redis数据做一致性校验。
![](https://support.huaweicloud.com/redisug-nosql/public_sys-resources/note_3.0-zh-cn.png)
- Redis迁移已完成或者已经进入增量状态。
- 需要ECS实例部署Redis-Full-Check开源工具，并确保与源端、目标端网络互通。
- 如果迁移任务处于增量状态，由于迁移源端和目标端间存在网络时延，无法确保校验时数据一致，如有条件，建议停止对源端的写入后再做校验。
- 业务使用Redis时往往存在给key设置过期时间，迁移时key过期行为会影响数据一致性，如果检验结果不一致，可能是由于key过期时间不一致导致。

- 云厂商DTS在迁移过程中会往目标端Redis写入临时探活key，校验时可能发现非业务数据，属于正常现象。
 
**操作步骤**：
1. 登录ECS实例，确保能连上源端和目标端Redis。
2. 部署[redis-full-check](https://github.com/alibaba/RedisFullCheck/releases?spm=a2c4g.11186623.0.0.7f6e5e58EyObOU)工具。
3. 执行以下命令进行数据校验。 
   /redis-full-check -s {源端IP}:{源端端口} -p {源端密码} -t {目标端IP}:{目标端端口} -a {目标端密码} -m 1
   表1参数说明 
   | 参数 | 参数                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 参数示例             |
   |:---|:---|:---|
   | -s | 源端Redis连接地址和端口。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | -s 10.0.0.1:6379 |
   | -p | 源端Redis密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                |
   | -t | 目标端Redis连接地址和端口。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | -t 10.0.0.2:6379 |
   | -a | 目标端Redis密码。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | -                |
   | -m | 校验模式： 1. 全量校验所有键值对。  2. 仅校验值的长度。  3. 仅校验key完整性。  4. 全量校验所有键值，但只校验大key的长度。   默认为模式2。 | -m 1             |
   | -q | 最大qps限制，默认15000。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | -q 5000          |
   | -d | 校验结果保存的文件名称，默认result.db。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | -d result.db     |
      
   
   
4. 查看校验结果文件。 
   校验默认执行三轮，输出三个校验结果文件，一般只需要看最后一个校验结果文件。
   - 执行sqlite3 result.db.3。
   
   - 执行select \* from key。
   
   - 查看是否存在异常的key。 ![](https://support.huaweicloud.com/redisug-nosql/zh-cn_image_0000002154295977.png)
     
   
   
   
   
 
#### 迁移性能参考
- 环境：Pika（单节点）和pika-port同时部署在华为云8U32GB的弹性云服务器上，目标端为8U16GB，3节点GeminiDB Redis实例。
- 预置数据：使用memtier_benchmark工具预置200GB数据。
- 迁移性能：约50000qps。
 
