1

[译] 迁移mysql的表到redis -m6米乐安卓版下载

原创 2022-03-16
1957

原文链接:https://www.mortensi.com/2021/12/migrate-a-mysql-table-to-redis/
原文作者:admin

1.png

在这篇文章中,我将列出一些从mysql逻辑复制一张表到redis的一些选项。我将使用经典的world数据库运行示例。 world数据库可以在这里,所以如果您想尝试这些示例,只需将它导入到您的mysql实例中。

mysql> use world; database changed mysql> show tables; ----------------- | tables_in_world | ----------------- | city | | country | | countrylanguage | ----------------- 3 rows in set (0.01 sec)

有多种方法可以将表格导入redis,让我们来看看其中的几种。在下面的例子中,我将选择一个数据类型,最类似于redis的传统表行。

redis哈希是字符串字段和字符串值之间的映射,所以它们是表示对象的完美数据类型(例如,一个用户有许多字段,如名字、姓氏、年龄等)

使用 select into outfile 导出csv格式,使用python导入

为了从mysql导出数据并将其导入redis,我们可以使用mysql 功能,它可以生成一个格式化的输出文件。特别是,我将确保字段用逗号分隔。让我们试一试:

mysql> select * into outfile '/tmp/city.csv' fields terminated by ',' enclosed by '"' lines terminated by 'n' from world.city; error 1290 (hy000): the mysql server is running with the --secure-file-priv option so it cannot execute this statement

噢,mysql默认配置禁止导出数据到文件系统。让我们在配置文件my.cnf中修复它:

[mysqld] secure_file_priv=/tmp

现在我可以导出:

mysql> select * into outfile '/tmp/city.csv' fields terminated by ',' enclosed by '"' lines terminated by 'n' from world.city; query ok, 4079 rows affected (0.01 sec)

这是示例:

"1","kabul","afg","kabol","1780000" "2","qandahar","afg","qandahar","237500" "3","herat","afg","herat","186800" "4","mazar-e-sharif","afg","balkh","127800" "5","amsterdam","nld","noord-holland","731200" "6","rotterdam","nld","zuid-holland","593321" "7","haag","nld","zuid-holland","440900" "8","utrecht","nld","utrecht","234323"

现在数据是csv格式,我能使用一个简单的python脚本导入它,下面是个可用的示例(参考说明设置python以连接到redis)。

#!/usr/bin/python3 import redis from csv import reader r = redis.redis(host='127.0.0.1', port=4321, password='') with open('/tmp/city.csv', 'r') as cities: csv_reader = reader(cities) for row in csv_reader: r.hset("city:" row[0], mapping={ "name" : row[1], "countrycode" : row[2], "district" : row[3], "population" : row[4] })

让我们检查下是否正确导入:

127.0.0.1:4321> scan 0 match city:* count 5
1) "3072"
2) 1) "city:2316"
   2) "city:749"
   3) "city:570"
   4) "city:3625"
   5) "city:3328"
   6) "city:1771"

我也可以验证hash项的内容:

127.0.0.1:4321> hgetall city:4059
1) "name"
2) "cary"
3) "countrycode"
4) "usa"
5) "district"
6) "north carolina"
7) "population"
8) "91213"

使用mysqldump导出csv格式

备份工具可作为客户端,可以从远端导出数据,而不需要修改让任何服务器配置。可以此来代替select into outfile,对有些人来说,它可能代表一个安全问题,因为它是在服务器本身导出行数据到文件系统,并需要启用。

mysqldump --host=127.0.0.1 --user=root --password --tab=/tmp --fields-enclosed-by='"' --fields-terminated-by=',' --lines-terminated-by='n' world city

一旦文件导出(mysqldump导出两个文件,表定义保存在city.sql文件,数据以csv格式保存在city.txt文件),数据可以按照说明导入。

使用riot导入csv备份

假设你有一个mysql表的csv备份,事实上,csv可以来自于任何数据源,比如excel表格,postgres等等。如果你不想编码来导入到redis,你可以使用riot(redis输入输出工具),用于将异构数据源迁移到redis。

2.png
redis输入输出工具: riot

redis输入/输出工具(riot)是一个工具集,其设计目的在于帮助您从redis导入导出数据。

在本节中,我将演示riot的csv导入工具,称之为。首先,安装它(我使用mac,但是您可以参考文档了解其他安装方法)

brew install redis-developer/tap/riot-file

安装后,测试帮助方法:

(redisvenv) bash-3.2$ riot-file --help the operation couldn’t be completed. unable to locate a java runtime. please visit http://www.java.com for information on installing java.

是的,您也需要从下载jre,完成后,继续:

(redisvenv) bash-3.2$ riot-file import hset --help usage: riot-file import hset [options] set hashes from input -h, --help show this help message and exit -s, --separator= key separator (default: :) -r, --remove remove key or member fields the first time they are used --ignore-missing ignore missing fields -p, --keyspace= keyspace prefix -k, --keys=... key fields --include=... fields to include --exclude=... fields to exclude

现在,我们必须将csv数据源映射到适当的hash数据结构。我们原始的csv文件第一行没有标题。如果我们想加标题,我们甚至可以按照顺序从mysql 中抽取。

注意:mysql select into outfile不会在导出的数据集添加头,这必须使用正确的sql语法手动添加,或编辑导出的csv文件。

mysql> select group_concat(column_name order by ordinal_position separator ',') from information_schema.columns where table_name='city' and table_schema='world'; ------------------------------------------------------------------- | group_concat(column_name order by ordinal_position separator ',') | ------------------------------------------------------------------- | id,name,countrycode,district,population | ------------------------------------------------------------------- 1 row in set (0.00 sec)

添加id,name,countrycode,district,population到csv文件的第一行。但是我们仍然可以继续手动执行映射。在这里,我们指定字段在csv文件中出现的顺序,指定表名(keyspace),及补充字段名(key)(例如city:1234)。

riot-file -h 127.0.0.1 -p 4321 import /tmp/city.csv --fields id name countrycode district population hmset --keyspace city --keys id

或者,如果csv文件有从mysql获得的头,我们可以添加--header参数来使用手动添加的csv头。

riot-file -h 127.0.0.1 -p 4321 import /tmp/city.csv --header hmset --keyspace city --keys id

使用 riot db 从mysql导入

为了从没有中间转储备份导入mysql,您可以编码一个方案,来连接源数据库和目标redis库,或者简单地使用。下面来安装它:

brew install redis-developer/tap/riot-db

然后像往常一样导入,指定表名和列名,提供正确的连接信息,显然,需要定义导入数据集的查询语句。

riot-db -h 127.0.0.1 -p 4321 import "select * from city" --url jdbc:mysql://root:oracle1*@127.0.0.1:3306/world hmset --keyspace city --keys id

导出并以resp格式做大量插入

到目前为止,我已经探索了一些逻辑方法,但是对于大量插入,最高速度需要达到百万个键,有一种不同的方法,即使用redis-cli的管道模式,读取数据的同时,立即发送到服务器。特别地,使用这种方法,我们将使用。关于大量插入的更多信息请参阅。

它可能导出resp格式的表,并转瞬流到redis服务器。让我们看看它是如何工作的。我们能使用sql来生成数据,并以这种格式发送到redis服务器:

*
$

$

...
$

这里:

  • args 是参数的数量
  • lenn 是参数跟随的长度
  • argn 是参数

假设我们要为mysql表中的每一行添加一个hash,每个hash将插入4个字段,在resp协议中生成转储的sql语句将是这样的:

select concat( "*10\r\n", '$', length(redis_cmd), '\r\n',redis_cmd, '\r\n','$', length(redis_key), '\r\n',redis_key, '\r\n', '$', length(hkey1), '\r\n',hkey1, '\r\n','$', length(hval1), '\r\n', hval1, '\r\n' '$', length(hkey2), '\r\n',hkey2, '\r\n','$', length(hval2), '\r\n', hval2, '\r\n' '$', length(hkey3), '\r\n',hkey3, '\r\n','$', length(hval3), '\r\n', hval3, '\r\n' '$', length(hkey4), '\r\n',hkey4, '\r\n','$', length(hval4), '\r\n', hval4, '\r\n' ) from ( select 'hset' as redis_cmd, concat('city:',id) as redis_key, 'name' as hkey1, name as hval1, 'countrycode' as hkey2, countrycode as hval2, 'district' as hkey3, district as hval3, 'population' as hkey4, population as hval4 from world.city ) as t;

保存sql到resp.sql文件,并用redis的管道模式从mysql流到redis:

bash-3.2$ mysql -h 127.0.0.1 -uroot -p -dworld --skip-column-names --raw

数据已经导入到redis服务器!

使用redis的mysql连接器:redis-connect-mysql

最后一节,我将介绍如何使用redis连接套件,特别是 。您可以阅读这份文档:

redis-connect-mysql第一次连接mysql时,它会读取所有模式的一致性快照。当快照创建完成,连接器将连续发送mysql的变更并生成相应的insert,update或delete事件。

因此,它不仅仅是一个迁移工具,还是一个连接异构数据库的复制和传输工具。redis cdc (变更数据捕捉)曾在redisconf 2021上演示,所以请查看演示的详细内容。

(译者注:这段视频在油管上,此处跳过。)

我现在没有运行使用rediscdc的示例,但是请查看来了解如何操作它。

清理

为了移除那些导入的hash值,您可以执行下面的命令:

redis-cli -p --scan --pattern city:* -i 0.01 | xargs redis-cli -p unlink

总结

现在,您能从mysql导出一张表,或者从其他的关系型数据库,任何可以导出csv的数据库,或者riot db,或者rediscdc能连接的多种数据库。

支持rediscdc的连接器在,支持riot db的连接器在。

接下来,您可能想知道您能用这些创建在redis实例中的哈希值做些什么。所以我在下篇文章中,将分享一些例子,关于在redis中存储、检索、更改、删除、索引和检索数据的命令。

那么现在呢? 你可能想知道你可以用这些在redis实例中创建的哈希值做什么。所以在下一篇文章中,我将分享几个在redis中存储、检索、更改、删除、索引和搜索数据的命令示例。别走开,我很快就会写的!

最后修改时间:2022-03-23 10:40:48
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
1人已赞赏
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

网站地图