使用redis-shake工具进行redis的数据同步

news2024/11/22 11:27:50

前言:

工作中将常遇到测试环境和正式环境的数据同步或者需要进行数据迁移,对于mysql数据库的方案倒是不少,但是redis中如何快速便捷的迁移呢?答案是阿里云提供的:redis-shake

RedisShake是阿里云基于豌豆荚开源的redis-port进行二次开发的一个支持Redis异构集群实时同步的工具,它和redis-migrate-tool相比较,我觉得它的优点在于支持前缀key的同步,支持多DB同步,而redis-migrate-tool 只能全量同步,并且如果源做了分库,同步到目标Redis的时候都同步到了db0一个库里面了,这对于做了分库场景的业务是不可行的。

基本功能

redis-shake它支持解析、恢复、备份、同步四个功能

  1. 恢复restore:将RDB文件恢复到目的redis数据库。
  2. 备份dump:将源redis的全量数据通过RDB文件备份起来。
  3. 解析decode:对RDB文件进行读取,并以json格式解析存储。
  4. 同步sync:支持源redis和目的redis的数据同步,支持全量和增量数据的迁移,支持单节点、主从版、集群版之间的互相同步。
  5. 同步rump:支持源redis和目的redis的数据同步,仅支持全量的迁移,采用scan和restore命令进行迁移,支持不同云厂商不同redis版本的迁移。

参考官方文档: https://github.com/alibaba/RedisShake 

基本原理

RedisShake同步原理

  1. 源Redis服务实例相当于主库,Redis-shake相当于从库,它会发送psync指令给源Redis服务实例。
  2. 源Redis实例先把RDB文件传输给 Redis-shake ,Redis-shake 会把RDB文件发送给目的实例。
  3. 源实例会再把增量命令发送给 Redis-shake ,Redis-shake负责把这些增量命令再同步给目的实例。


RedisShake执行过程

  1. 启动Redis-shake进程,这个进程模拟了一个 Redis 实例,Redis-shake的基本原理就是模拟一个Slave从节点加入源Redis集群,然后进行增量的拉取(通过psync命令)。
  2. Redis-shake进程和数据迁出的源实例进行数据的全量拉取同步,并回放,这个过程和 Redis 主从实例的全量同步是类似的

版本迭代特性

现在 redis-shake 有两个主版本:
redis-shake 2.x:持续更新 3 年,目前停止更新与答疑,遇到问题推荐尝试 3.x 版本
redis-shake 3.x:基于 redis-shake 2.x 重写,代码可读性高,性能较佳 

部署和使用 

1、部署安装redis-shake

1.1源端创建测试数据也可以可视化工具自行添加一些测试数据

[root@localhost ~]# for line in {1..10000};do /opt/redis6/bin/redis-cli -h 192.168.1.191 -p 7001 -c -a 1UEJjjGfYZU7dCWy set ops_${line} ${line}; done

 2、下载解压redis-shake文件

[root@localhost ~]# mkdir redis-shake && cd redis-shake
[root@localhost redis-shake]# wget https://github.com/alibaba/RedisShake/releases/download/v3.1.7/redis-shake-linux-amd64.tar.gz
[root@localhost redis-shake]# tar axf redis-shake-linux-amd64.tar.gz

一、数据迁移实操

迁移环境信息如下:

主机IP操作系统Redis版本CPU架构端口角色
192.168.1.191Centos7.66.2.8x86_647001源主机
192.168.1.192Centos7.66.2.8x86_647001目标主机

3、修改配置文件(sync.toml)

type = "sync" # 同步机制实现

[source] # 源Redis服务实例
version = 5.0 # 填写Redis源服务版本, 例如:2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ...。
address = "127.0.0.1:6379" # 源Redis服务实例 地址+端口
username = "" # 如果Redis没有配置ACL,则可以不填写,否则需要填写用户名 
password = "" # 如果Redis没有配置ACL,则可以不填写,否则需要填写密码
tls = false # 是否开启tls安全机制
elasticache_psync = "" # 是否支持AWS的elasticache

[target]
type = "standalone" # 选择Redis的类型:"standalone:单机模式" or "cluster:集群模式"
version = 5.0  # 填写Redis源服务版本, 例如:2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ...。
# 如果目标Redis服务实例属于cluster集群模式, 那么可以写入其中一个节点的地址和端口.
# redis-shake 会通过`cluster nodes` 命令获取其他的节点地址和端口
address = "127.0.0.1:6380" # 填写的对应的ip加端口
username = "" # 如果Redis没有配置ACL,则可以不填写,否则需要填写用户名 
password = "" # 如果Redis没有配置ACL,则可以不填写,否则需要填写密码
tls = false # 是否开启tls安全机制

[advanced]
dir = "data" # 数据同步的存储目录

# 设置使用的最大CPU核心数, 如果设置了0 代表着 使用 runtime.NumCPU() 实际的cpu cores数量
ncpu = 4

# 开启pprof性能检测的port, 0代表着禁用
pprof_port = 0 

# 开启metric port端口, 0代表着禁用
metrics_port = 0

# log的相关设置
log_file = "redis-shake.log" # 设置对应的日志文件名称
log_level = "info" # debug, info or warn # 设置对应的日志级别
log_interval = 5 # in seconds # 日志打印频次

# redis-shake gets key and value from rdb file, and uses RESTORE command to
# create the key in target redis. Redis RESTORE will return a "Target key name
# is busy" error when key already exists. You can use this configuration item
# to change the default behavior of restore:
# panic:   redis-shake will stop when meet "Target key name is busy" error.
# rewrite: redis-shake will replace the key with new value.
# ignore:  redis-shake will skip restore the key when meet "Target key name is busy" error.
rdb_restore_command_behavior = "rewrite"  # restore的操作类型:panic, rewrite or skip

# pipeline的大小数量阈值
pipeline_count_limit = 1024

# Client query buffers accumulate new commands. They are limited to a fixed
# amount by default. This amount is normally 1gb.
target_redis_client_max_querybuf_len = 1024_000_000

# In the Redis protocol, bulk requests, that are, elements representing single
# strings, are normally limited to 512 mb.
target_redis_proto_max_bulk_len = 512_000_000

同步日志注释
当打印的日志出现send RDB finished,表示完成全量数据迁移,接下来进入增量数据迁移阶段。

日志信息中各参数说明如下:

  • allowOps:表示每秒向目标库发送多少条命令。 说明 通常当allowOps为0时,表示数据迁移完成,可以停止redis-shake。但源库会定时发送PING命令,所以allowOps偶尔不为0。
  • disallowOps:表示每秒过滤的命令数。
  • entryId:从1开始计数,表示redis-shake共处理多少条命令。
  • InQueueEntriesCount:表示还剩余多少条命令待发送。 暂停向源库写入数据,等待返回日志中allowOps对应值连续多次为0时,使用Ctrl+C组合键停止运行redis-shake。 此时目标库的数据与源库完全一致,您可以将业务的数据库服务由自建Redis数据库切换至Tair或Redis实例。

 toml文件的编写方式
单机 -> 单机 配置格式:

type = "sync"
[source]  
address = "127.0.0.1:6379"
password = "123456"  ## 根据自身密码填写

[target]  
type = "standalone" #这里type属性设置一定为standalone
address = "127.0.0.1:6379" 
password = "123456" ## 根据自身密码填写

启动 redis-shake:
root@ubuntu20-171:RedisShake# ./redis-shake sync.toml

单机->集群 配置格式:

type = "sync"
[source]  #数据源配置
address = "127.0.0.1:6379"
password = "1234566"

[target]  #目的源配置
type = "cluster"   #这里type属性设置一定为cluster
address = "127.0.0.1:6379" # 这里写集群中的任意一个节点的地址即可
password = "1234566"

启动 redis-shake:
root@ubuntu20-171:RedisShake# ./redis-shake sync.toml

 集群 -> 集群 配置格式:
在 RedisShake V3系列版本,也就是当前使用最多的版本中,集群与集群之间的redis数据同步,统一在单机到集群的基础上,为每一个数据源端的redis master节点建立一个shake进程

⚠️注意:不要在同一个目录启动多个 redis-shake,因为 redis-shake 会在本地存储临时文件,多个 redis-shake 之间的临时文件会干扰,正确做法是建立多个目录。

配置
修改 sync.toml:

type = "sync"

[source]
address = "192.168.0.1:6379" # 集群 C 中任意一个节点地址
password = "r-ccccc:xxxxx"

[target]
type = "cluster"
address = "192.168.1.1:6380" # 集群 D 中任意一个节点地址
password = "r-ddddd:xxxxx"

启动 redis-shake:
root@ubuntu20-171:RedisShake# cd bin/cluster_helper
root@ubuntu20-171:cluster_helper# python3 cluster_helper.py ../redis-shake ../sync.toml 

参数 1 是 redis-shake 可执行程序的路径
参数 2 是配置文件路径

 2.3、redis-shake执行数据迁移

1、执行下述命令启动redis-shake,redis-shake将开始执行数据迁移

[root@localhost redis-shake]# ./redis-shake sync.toml

日志信息

同步分为三个阶段:

等待源端save rdb完毕,日志如下:

[root@localhost redis-shake]# ./redis-shake sync.toml
2024-11-20 23:16:45 INF GOOS: linux, GOARCH: amd64
2024-11-20 23:16:45 INF Ncpu: 4, GOMAXPROCS: 4
2024-11-20 23:16:45 INF pid: 5493
2024-11-20 23:16:45 INF pprof_port: 0
2024-11-20 23:16:45 INF No lua file specified, will not filter any cmd.
2024-11-20 23:16:45 INF no password. address=[192.168.48.131:6319]
2024-11-20 23:16:45 INF redisClusterWriter load cluster nodes. line=b4cc6c47038acb2a5f1198f23473d757d0991b24 127.0.0.1:6319@16319 myself,master - 0 1732173403000 1 connected 0-5460
2024-11-20 23:16:45 INF no password. address=[127.0.0.1:6319]
2024-11-20 23:16:45 INF redisWriter connected to redis successful. address=[127.0.0.1:6319]
2024-11-20 23:16:45 INF redisClusterWriter load cluster nodes. line=61cdca1ce4f7524e7278081474168361f2036d39 127.0.0.1:6339@16339 master - 0 1732173404370 3 connected 10923-16383
2024-11-20 23:16:45 INF no password. address=[127.0.0.1:6339]
2024-11-20 23:16:45 INF redisWriter connected to redis successful. address=[127.0.0.1:6339]
2024-11-20 23:16:45 INF redisClusterWriter load cluster nodes. line=ef3dd5f8304d590eb730b7a9900a7d5a2ccbab02 127.0.0.1:6329@16329 master - 0 1732173401171 2 connected 5461-10922
2024-11-20 23:16:45 INF no password. address=[127.0.0.1:6329]
2024-11-20 23:16:45 INF redisWriter connected to redis successful. address=[127.0.0.1:6329]
2024-11-20 23:16:45 INF redisClusterWriter connected to redis cluster successful. addresses=[127.0.0.1:6319 127.0.0.1:6339 127.0.0.1:6329]
2024-11-20 23:16:45 INF no password. address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF psyncReader connected to redis successful. address=[192.168.0.111:7005]
2024-11-20 23:16:45 WRN remove file. filename=[133117.aof]
2024-11-20 23:16:45 WRN remove file. filename=[dump.rdb]
2024-11-20 23:16:45 INF start save RDB. address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF send [replconf listening-port 10007]
2024-11-20 23:16:45 INF send [PSYNC ? -1]
2024-11-20 23:16:45 INF receive [FULLRESYNC 2f2ce402b674be6aa3df35b1a9a27073bd67275c 135609]
2024-11-20 23:16:45 INF source db is doing bgsave. address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF source db bgsave finished. timeUsed=[0.12]s, address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF received rdb length. length=[1094]
2024-11-20 23:16:45 INF create dump.rdb file. filename_path=[dump.rdb]
2024-11-20 23:16:45 INF save RDB finished. address=[192.168.0.111:7005], total_bytes=[1094]

全量同步阶段
数据量大的话会显示进度百分比:(我dev环境数据量小)日志如下:


2024-11-20 23:16:45 INF start send RDB. address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF RDB version: 7
2024-11-20 23:16:45 INF RDB AUX fields. key=[redis-ver], value=[3.2.100]
2024-11-20 23:16:45 INF RDB AUX fields. key=[redis-bits], value=[64]
2024-11-20 23:16:45 INF RDB AUX fields. key=[ctime], value=[1732173405]
2024-11-20 23:16:45 INF RDB AUX fields. key=[used-mem], value=[0]
2024-11-20 23:16:45 INF RDB resize db. db_size=[10], expire_size=[0]
2024-11-20 23:16:45 INF send RDB finished. address=[192.168.0.111:7005], repl-stream-db=[0]
2024-11-20 23:16:45 INF start save AOF. address=[192.168.0.111:7005]
2024-11-20 23:16:45 INF AOFWriter open file. filename=[135609.aof]
2024-11-20 23:16:46 INF AOFReader open file. aof_filename=[135609.aof]
   ## 全量完成

## 显示 send RDB finished 说明全量完成

 增量同步
日志如下:

2024-11-20 23:16:50 INF syncing aof. allowOps=[2.00], disallowOps=[0.00], entryId=[9], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[0], aofAppliedOffset=[0]
2024-11-20 23:16:55 INF syncing aof. allowOps=[0.20], disallowOps=[0.00], entryId=[10], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[135623], aofAppliedOffset=[135623]
2024-11-20 23:17:00 INF syncing aof. allowOps=[0.00], disallowOps=[0.00], entryId=[10], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[135623], aofAppliedOffset=[135623]
2024-11-20 23:17:05 INF syncing aof. allowOps=[0.20], disallowOps=[0.00], entryId=[11], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[135637], aofAppliedOffset=[135637]
2024-11-20 23:17:10 INF syncing aof. allowOps=[0.00], disallowOps=[0.00], entryId=[11], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[135637], aofAppliedOffset=[135637]
2024-11-20 23:17:15 INF syncing aof. allowOps=[0.20], disallowOps=[0.00], entryId=[12], InQueueEntriesCount=[0], unansweredBytesCount=[0]bytes, diff=[0], aofReceivedOffset=[135651], aofAppliedOffset=[135651]

 出现字样syncing aof. allowOps=[0.00] 或者出现syncing aof. allowOps=[0.00]的频率很高 说明 当前增量同步完成 可以ctrl+c停止redis-shake 进程,但是 一般不会为0 或者 因为有client在一直连接

查看源端和目标端的情况
源端

127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:1  ### 源端会启动一个redis-shake的从节点
slave0:ip=127.0.0.1,port=10007,state=online,offset=1040,lag=0 ###shake进程
master_failover_state:no-failover
master_replid:b20dfd6f617c867cfaf0910c08be627fe7b922d7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1040
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:104857600
repl_backlog_first_byte_offset:229
repl_backlog_histlen:812

127.0.0.1:6379> info  Keyspace   ## 查看比对key数量
# Keyspace
db0:keys=6,expires=0,avg_ttl=0
db2:keys=3,expires=0,avg_ttl=0
db10:keys=3,expires=0,avg_ttl=0

目标端

127.0.0.1:7000> info Replication
# Replication
role:master   ### 目标端 还是master角色
connected_slaves:0
master_failover_state:no-failover
master_replid:1017a92f7fd8447d304172796ea6044a1f801e26
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:104857600
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

127.0.0.1:7000> info  Keyspace  ## 对比key数量
# Keyspace
db0:keys=6,expires=0,avg_ttl=0
db2:keys=3,expires=0,avg_ttl=0
db10:keys=3,expires=0,avg_ttl=0

注意事项
如果目标库的数据淘汰策略(maxmemory-policy)配置为noeviction以外的值,可能导致目标库的数据与源库不一致
如果源库中的某些Key使用了过期(expire)机制,由于可能存在Key已过期但未被及时删除的情形,所以在目标库中查看(如通过info命令)到的Key数量会比源库的Key数量少

以上就是这期全部内容,感谢观看 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2245293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

轻松实现文件远程传输:使用PicoShare搭建轻量级文件共享系统

文章目录 前言1. 本地安装Docker2. 本地部署PicoShare3. 如何使用PicoShare4. 公网远程访问本地 PicoShare4.1 内网穿透工具安装4.2 创建远程连接公网地址 5. 固定PicoShare公网地址 前言 什么是PicoShare? PicoShare 是一个由 Go 开发的轻量级开源共享文件系统。…

路由缓存后跳转到新路由时,上一路由中的tip信息框不销毁问题解决

上一路由tip信息框不销毁问题解决 路由缓存篇问题描述及截图解决思路关键代码 路由缓存篇 传送门 问题描述及截图 路由缓存后跳转新路由时,上一个路由的tip信息框没销毁。 解决思路 在全局路由守卫中获取DOM元素,通过css去控制 关键代码 修改文…

iOS 18.2 Beta 4开发者预览版发布,相机新增辅助功能

昨天刚连发iOS 18.1.1正式版、iOS 17.7.2正式版,今天凌晨,苹果就又发布iOS 18.2 Beta 4,据了解iOS18.2正式版将在 12 月初发布。那么这次的更新又有哪些变化呢?下面我们就来一起了解一下。 iOS 18.2 Beta 4的版本号为:…

PCB 间接雷击模拟

雷击是一种危险的静电放电事件,其中两个带电区域会瞬间释放高达 1 千兆焦耳的能量。雷击就像一个短暂而巨大的电流脉冲,会对建筑物和电子设备造成严重损坏。雷击可分为直接和间接两类,其中间接影响是由于感应能量耦合到靠近雷击位置的物体。间…

易语言学习-cnblog

易语言数据类型 数值转换命令(自己学) 数值到大写()将一个数值转换到中文读法,第二个参数为是否为简体。 数值到大写(123.44,假) 猜测结果 数值到金额()将双…

接口小练习

文章目录 1.字符串最后一个单词的长度2.字符串中的第一个唯一字符3.验证回文串 1.字符串最后一个单词的长度 计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾) 输入描…

26届JAVA 学习日记——Day14

2024.11.21周四 今天仍然在补充基础知识,项目进度较慢,明天再回顾一下Java8的新特性。 八股 操作系统 什么是缓冲区溢出? 缓冲区溢出是一种常见的计算机安全漏洞,它发生在程序试图将过多的数据写入缓冲区(即一块用…

Element UI 组件库详解【Vue】

文章目录 一、引言二、安装并使用1. 安装2. 使用 三、常见组件说明1. 基础组件2. 布局组件3. 布局容器4. 选择框组件5. 输入框组件6. 下拉框组件7. 日期选择器8. 上传组件9. 表单组件10. 警告组件11. 提示组件12. 表格组件 一、引言 官方网站,element.eleme.cn El…

【腾讯云产品最佳实践】腾讯云CVM入门技术与实践:通过腾讯云快速构建云上应用

目录 前言 什么是腾讯云CVM? 腾讯云CVM的技术优势 基于最佳技术实践,使用腾讯云CVM搭建应用 1. 开通CVM实例 2. 连接CVM实例 3. 配置Web环境 4. 部署PHP应用 腾讯云CVM行业应用案例:电商平台的双十一攻略 1. 弹性伸缩解决高并发问题…

2024信创数据库TOP30之达梦DM8

近年来,中国信创产业快速崛起,其中数据库作为基础软件的重要组成部分,发挥了至关重要的作用。近日,由DBC联合CIW/CIS共同发布的“2024信创数据库TOP30”榜单正式揭晓,汇聚了国内顶尖的数据库企业及产品,成为…

SSA-XGBoost分类预测 | Matlab实现SSA-XGBoost麻雀算法优化XGBoost的多特征分类预测

分类预测 | Matlab实现SSA-XGBOOST麻雀算法优化XGBOOST的多特征分类预测 目录 分类预测 | Matlab实现SSA-XGBOOST麻雀算法优化XGBOOST的多特征分类预测效果一览基本介绍程序设计参考资料效果一览 基本介绍 Matlab实现SSA-XGBoost麻雀算法优化XG

c#编码技巧(十九):各种集合特点汇总

.NET 常用集合对比: .NET 常见的线程安全集合 .NET 只读集合

springboot基于Hadoop的NBA球员大数据分析与可视化(1)(6)

摘 要 科学技术日新月异,人们的生活都发生了翻天覆地的变化,NBA球员大数据分析与可视化系统当然也不例外。过去的信息管理都使用传统的方式实行,既花费了时间,又浪费了精力。在信息如此发达的今天,可以通过网络这个媒…

鸿蒙多线程开发——线程间数据通信对象01

1、线程间通信 线程间通信指的是并发多线程间存在的数据交换行为。由于ArkTS语言兼容TS/JS,其运行时的实现与其它所有的JS引擎一样,都是基于Actor内存隔离的并发模型提供并发能力。 对于不同的数据对象,在ArkTS线程间通信的行为是有差异的&…

goland单元测试

一、单元测试的概念 1.1 什么是单元测试,有什么用? 单元测试是针对于函数的测试,用来保证该函数的逻辑正确性。 1.2 单元测试的要求? 1. 单元测试在正式上线之前应该全部自动执行,并且需要保证全部通过 2. 单元测试需…

ArcGIS定义投影与投影的区别(数据和底图不套合的原因和解决办法)

今天介绍一下ArcGIS中定义投影与投影的区别。 给大家解惑一下为什么经常出现自己的数据无法和底图套合的情况。 一 目录 1、ArcGIS定义投影与投影的概念区别 2、ArcGIS定义正确的坐标系 3、ArcGIS动态投影实现套合 4、ArcGIS地理坐标系转投影坐标系(错误做法&am…

语义通信论文略读(十七)可变长编码的语义通信+Extended Reality

Semantic Communications With Variable-Length Coding for Extended Reality 用于扩展现实的带可变长度编码的语义通信 作者: Bowen Zhang, Zhijin Qin, Geoffrey Ye Li 所属机构: 伦敦帝国理工学院电气与电子工程系; 清华大学电子工程系 关键词: 扩展现实,联…

IDEA2019搭建Springboot项目基于java1.8 解决Spring Initializr无法创建jdk1.8项目 注释乱码

后端界面搭建 将 https://start.spring.io/ 替换https://start.aliyun.com/ 报错 打开设置 修改如下在这里插入代码片 按此方法无果 翻阅治疗后得知 IDEA2019无法按照网上教程修改此问题因此更新最新idea2024或利用插件Alibaba Clouod Toolkit 换用IDEA2024创建项目 下一步…

网络编程 day1.2~day2——TCP和UDP的通信基础(TCP)

笔记脑图 作业&#xff1a; 1、将虚拟机调整到桥接模式联网。 2、TCP客户端服务器实现一遍。 服务器 #include <stdio.h> #include <string.h> #include <myhead.h> #define IP "192.168.60.44" #define PORT 6666 #define BACKLOG 20 int mai…

BLIP-2模型的详解与思考

大模型学习笔记------BLIP-2模型的详解与思考 1、BLIP-2框架概述2、BLIP-2网络结构详解3、BLIP-2的几点思考 上一篇文章上文中讲解了 BLIP&#xff08;Bootstrapping Language-Image Pretraining&#xff09;模型的一些思考&#xff0c;本文将讲述一个BLIP的升级版 BLIP-2&am…