本章节将介绍怎样为 MinIO 中某个存储桶添加 MySQL 事件通知。
注意:MinIO 要求 MySQL 版本 5.7.8 及以上,MinIO 使用了 MySQL5.7.8 版本引入的 JSON 数据类型。我们使用的是 MySQL 5.7.24 进行的测试。
在 Windows 上面如何安装 MySQL 数据库这里不再赘述,不会的读者可执行查阅资料。
为了演示,我们将在数据库中创建了一个 miniodb 的数据库来存储事件信息,默认使用 root 账号。
MinIO MySQL 通知也支持两种格式:
namespace:如果使用 namespace 格式,MinIO 将存储桶里的对象同步成数据库表中的行。每一行有两列:key_name 和 value。key_name 是这个对象的存储桶名字加上对象名,value 都是一个有关这个 MinIO 对象的 JSON 格式的事件数据。如果对象更新或者删除,表中相应的行也会相应的更新或者删除。
access:如果使用的是 access 格式,MinIO 将事件添加到表里,行有两列:event_time 和 event_data。event_time 是事件在 MinIO server 里发生的时间,event_data 是有关这个 MinIO 对象的 JSON 格式的事件数据。在这种格式下,不会有行会被删除或者修改。
下面的步骤展示的是如何在 namespace 格式下使用通知目标,access 方式读者执行研究,和 namespace 类似。
打开 MinIO 数据目录下面的 .minio.sys 目录,编辑 .minio.sys\config\config.json 文件。找到 “notify_mysql” 配置项,添加 MySQL 配置信息。配置如下:
{ //... "notify_mysql": { "_": [{ "key": "enable", "value": "on" }, { "key": "format", "value": "namespace" }, { "key": "dsn_string", "value": "root:aaaaaa@tcp(127.0.0.1:3306)/miniodb" }, { "key": "table", "value": "minio_images" }, { "key": "queue_dir", "value": "" }, { "key": "queue_limit", "value": "0" }, { "key": "max_open_connections", "value": "2" } ] }, //... }
其中:
dsn_string:MySQL 数据源名称连接字符串,格式为 "<user>:<password>@tcp(<host>:<port>)/<database>",例如:root:aaaaaa@tcp(127.0.0.1:3306)/miniodb,其中 root 为用户名,aaaaaa 为密码,miniodb 为数据库名称;
table:用来保存存储桶对象新增/修改事件信息的数据库表名,表是自动创建的。启动 MinIO 服务时可能会抛出如下错误信息:
DeploymentID: 183f33e6-1876-40d9-9ccd-96c4404c6387 Error: Error 1071: Specified key was too long; max key length is 3072 bytes (*mysql.MySQLError) 13: internal\logger\logonce.go:54:logger.(*logOnceType).logOnceIf() 12: internal\logger\logonce.go:94:logger.LogOnceIf() 11: internal\event\target\mysql.go:387:target.NewMySQLTarget() 10: internal\config\notify\parse.go:253:notify.FetchRegisteredTargets() 9: internal\config\notify\parse.go:74:notify.RegisterNotificationTargets() 8: internal\config\notify\parse.go:65:notify.GetNotificationTargets() 7: cmd\config-current.go:521:cmd.lookupConfigs() 6: cmd\config-current.go:707:cmd.loadConfig() 5: cmd\config.go:236:cmd.initConfig() 4: cmd\config.go:196:cmd.(*ConfigSys).Init() 3: cmd\server-main.go:387:cmd.initAllSubsystems() 2: cmd\server-main.go:323:cmd.initServer() 1: cmd\server-main.go:535:cmd.serverMain()
这是因为创建表时指定的键太长,MySQL 最大密钥长度为 3072 字节。可通过手动创建数据表解决该问题,创建表的 SQL 代码如下:
CREATE TABLE `minio_images` ( `key_name` varchar(1000) DEFAULT NULL, `value` longtext ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
format:指定保存格式,如果是“namespace”数据库中保存当前存储桶/对象列表信息;如果是“access”数据库中保存对象操作的日志,默认为“namespace”
queue_dir:指定未送达消息的暂存目录,例如:'/home/events'
queue_limit:未送达消息的最大限制,默认为“100000”
max_open_connections:与数据库的最大打开连接数,默认为“2”
comment:可选地为此设置添加注释进行说明
配置完成后,启动 MinIO 服务将会看见如下信息:
+----------------------------------------------------------------+ | You are running an older version of MinIO released 1 month ago | | Update: Run `mc admin update` | +----------------------------------------------------------------+ Endpoint: http://169.254.120.173:9000 http://192.168.0.101:9000 http://169.254.143.26:9000 http://192.168.31.10:9000 http://192.168.192.1:9000 http://172.20.240.1:9000 http://172.30.224.1:9000 http://127.0.0.1:9000 RootUser: root RootPass: mypassword IAM initialization complete SQS ARNs: arn:minio:sqs::_:mysql ....
其中的“arn:minio:sqs::_:mysql”将在后面给存储桶添加事件通知时用到。
我们现在可以创建一个 images 存储桶,在该存储桶上面开启事件通知。一旦有文件被创建或者覆盖,就会在数据库表中插入或者删除数据。
要配置这种存储桶通知,我们需要用到前面步骤 MinIO 输出的 ARN 信息“arn:minio:sqs::_:mysql”。
使用 mc 客户端执行如下脚本去开启通知:
# 使用客户端命令,在本地 MinIO 服务器中创建 images 存储桶 D:\server\minio>mc mb local/images Bucket created successfully `local/images`. # 为刚刚创建的 images 存储桶添加事件通知 # 使用 --suffix 选项指定仅仅上传/删除 jpg 格式图片才触发事件 D:\server\minio>mc event add local/images arn:minio:sqs::_:mysql --suffix=".jpg" Successfully added arn:minio:sqs::_:mysql # 查看 images 存储桶上面的事件 D:\server\minio>mc event list local/images arn:minio:sqs::_:mysql s3:ObjectCreated:*,s3:ObjectRemoved:*,s3:ObjectAccessed:* Filter: suffix=".jpg"
使用浏览器访问 http://localhost:9000 ,使用 Access Key 和 Securet Key 登陆到后台。手动添加两张图片到 images 存储桶,如下图:
连接到 miniodb 数据库,查看 minio_images 数据表,内容如下:
上面表中,插入了两条记录,分别对于 images 存储桶下面的 221425.jpg 和 221406.jpg 对象。