对象 Lambda 是 MinIO 中的一项功能,它允许对请求的数据进行即时自定义,使其成为对敏感信息进行脱敏、数据丰富或更改数据格式(无需修改原始存储数据)等场景的完美解决方案。这种方法比创建和维护同一数据集的多个最新副本更具成本效益,并简化了 MinIO 存储桶中的数据处理。
例如,假设一个 MinIO 存储桶包含一个从商业平台创建的数据集,其中包含个人可识别信息 (PII),例如信用卡号码。为了确保合规性,对象 Lambda 使 MinIO 系统管理员能够在数据从 MinIO 中检索时对其进行控制。这篇博客提供了针对此场景的教程。
对象 Lambda 和 MinIO 存储桶通知之间的差异
MinIO 对象 Lambda 旨在对对象内部进行实时内容转换。Lambda 处理程序由 GET 请求激活,它转换对象数据,并将修改后的版本传递回 MinIO,而不会对原始数据进行任何更改——这对维护不可变记录至关重要。
MinIO 存储桶通知 使管理员能够根据特定对象或存储桶事件将事件驱动的通知分派到外部服务,镜像 S3 事件通知的功能。在为远程目标选择异步 (快速但可能丢失事件) 或同步 (更谨慎但可靠) 通知时,关键取决于具体优先级。
对象 Lambda 擅长需要动态内容转换的场景,而存储桶通知则在协调针对外部服务的事件驱动警报方面处于领先地位。最终的决定取决于具体的用例——是涉及即时对象修改还是 MinIO 环境中事件的协调通知。
先决条件
你可以克隆此项目的仓库 此处。
创建对象 Lambda 处理程序
使用 requirements.txt 文件安装先决条件。
pip install -r requirements.txt
“Flask 运行”以下 脚本:
from flask import Flask, request, abort, make_response
import requests
import json
app = Flask(__name__)
@app.route('/', methods=['POST'])
def get_webhook():
if request.method == 'POST':
# obtain the request event from the 'POST' call
event = request.json
object_context = event["getObjectContext"]
# Get the presigned URL to fetch the requested
# original object from MinIO
s3_url = object_context["inputS3Url"]
# Extract the route and request token from the input context
request_route = object_context["outputRoute"]
request_token = object_context["outputToken"]
# Get the original S3 object using the presigned URL
r = requests.get(s3_url)
original_object = r.content.decode('utf-8')
# Transform the JSON object by anonymizing the credit card number
transformed_object = anonymize_credit_card(original_object)
# Write object back to S3 Object Lambda
# response sends the transformed data
# back to MinIO and then to the user
resp = make_response(transformed_object, 200)
resp.headers['x-amz-request-route'] = request_route
resp.headers['x-amz-request-token'] = request_token
return resp
else:
abort(400)
def anonymize_credit_card(original_object):
# Assume the original_object is a JSON string
data = json.loads(original_object)
# Check if the JSON is a list of transactions
if isinstance(data, list):
# Anonymize the credit card number in each transaction by keeping only the last four digits
for transaction in data:
if 'credit_card_number' in transaction:
transaction['cc_last_four_digits'] = transaction.pop('credit_card_number')[-4:]
# Convert the updated data back to JSON
transformed_object = json.dumps(data)
return transformed_object
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
此处理程序脚本中命令的详细分解可以在 文档 和其他 博客文章 中找到。关键部分是 getObjectContext
,它具有连接到 MinIO 的输入和输出。以下是其属性的分解
- inputS3Url: 提供给 Lambda 函数的用于下载原始对象的预签名 URL。这消除了 Lambda 函数需要 MinIO 凭证的必要性,从而简化了对对象转换的关注,无需承担凭证管理的负担。
- outputRoute: 当 Lambda 函数生成转换后的对象时,包含在响应标头中的路由令牌。MinIO 使用此令牌来进一步验证传入响应的有效性。
- outputToken: Lambda 函数返回转换后的对象后,附加到响应标头的令牌。MinIO 使用此令牌来验证和验证传入响应的完整性。
处理程序完成的主要转换是 anonymize_credit_card(original_object)
函数。此函数检查 MinIO 存储桶中的数据是否包含信用卡信息,然后转换字段,使其只保留最后四位数字。最后,此函数在列表中的每个字典中添加一个新的键 cc_last_four_digits
,并使用 .pop()
方法删除原始的 credit_card_number
键。
你应该会收到一条类似于此消息,表明 Flask 应用程序已启动并运行。
/Users/brennabuuck/PycharmProjects/objectlambdas/venv/bin/python -m flask run
* Serving Flask app 'app.py'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
启动 MinIO
运行以下命令启动 MinIo。
MINIO_LAMBDA_WEBHOOK_ENABLE_function=on \
MINIO_LAMBDA_WEBHOOK_ENDPOINT_function=http://127.0.0.1:5000 \
minio server ~/data
我将 Lambda 函数目标命名为 `function`,但你可以根据需要将其命名为其他名称,例如 MINIO_LAMBDA_WEBHOOK_ENABLE_<my_cool_function_name>
,以及其他 _LAMBDA_
变量。
命令执行后,你应该在终端中看到对象 Lambda ARN。
MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://gnu.ac.cn/licenses/agpl-3.0.html>
Version: RELEASE.2023-11-06T22-26-08Z (go1.21.3 darwin/arm64)
Status: 1 Online, 0 Offline.
S3-API: http://192.168.4.68:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
Console: http://192.168.4.68:50149 http://127.0.0.1:50149
RootUser: minioadmin
RootPass: minioadmin
Object Lambda ARNs: arn:minio:s3-object-lambda::function:webhook
生成数据
运行此 脚本 生成一个名为 pos_transactions.json
的 JSON 文件,其中包含伪造的销售点 (POS) 数据,如果尚未存在,则创建一个名为 anon-commerce-data
的 MinIO 存储桶,然后将该伪造数据上传到 anon-commerce-data
存储桶中。
运行脚本后,你的终端应会通知你文件已生成并上传。
Bucket 'anon-commerce-data' created successfully.
File 'fake_pos_transactions.json' uploaded successfully to 'anon-commerce-data' bucket.
minio-object-lambda-data-generator-1 exited with code 0
你可以导航到 http://127.0.0.1:9001
,访问 MinIO 控制台,以验证存储桶及其数据是否已安全到达。
MinIO 的用户名和密码默认为 minioadmin
和 minioadmin
。

运行以下 Python 脚本 以调用对象 Lambda,生成预签名 URL,并使用该预签名 URL 检索新转换的数据。在生产环境中,你可以将行为从打印更改为可能上传到存储桶,以供你的微服务进一步处理。
from minio import Minio
from datetime import timedelta
import requests
# Set your Minio server information
minio_endpoint = '127.0.0.1:9000'
minio_access_key = 'minioadmin'
minio_secret_key = 'minioadmin'
# Initialize a Minio client
s3Client = Minio(minio_endpoint, access_key=minio_access_key, secret_key=minio_secret_key, secure=False)
# Set lambda function target via `lambdaArn`
lambda_arn = 'arn:minio:s3-object-lambda::function:webhook'
# Generate presigned GET URL with lambda function
bucket_name = 'anon-commerce-data'
object_name = 'fake_pos_transactions.json'
expiration = timedelta(seconds=1000) # Expiration time in seconds
req_params = {'lambdaArn': lambda_arn}
presigned_url = s3Client.presigned_get_object(bucket_name, object_name, expires=expiration, response_headers=req_params)
print(presigned_url)
# Use the presigned URL to retrieve the data using requests
response = requests.get(presigned_url)
if response.status_code == 200:
content = response.content
print("Transformed data:\n", content)
else:
print("Failed to download the data. Status code:", response.status_code, "Reason:", response.reason)
查看数据
给定 JSON 对象输入如下所示
[
{
"transaction_id": 7247,
"amount": 63.59,
"currency": "USD",
"credit_card_number": "3506372205690474",
"timestamp": "2023-11-08T12:00:00"
}
]
调用脚本的输出将如下所示
[
{
"transaction_id": 7247,
"amount": 63.59,
"currency": "USD",
"cc_last_four_digits": "1014",
"timestamp": "2023-11-08T12:00:00"
}
]
结论
通过遵循这些说明,你已经为将 MinIO 对象 Lambda 集成到你的数据处理管道中奠定了坚实的基础,以确保数据合规性和安全性,并且成本效益高,效率高。
本教程展示了在请求数据时转换数据的简单性,同时展示了 MinIO 对象 Lambda 的多功能性和用户友好性。这些特性,以及 MinIO 的高性能和可扩展性,使你的数据处理基础设施能够获得最佳功能和未来发展。MinIO 致力于提供一流的对象存储,确保无论你操作的规模或复杂程度如何,都能无缝满足你的法规遵从性需求。
如有任何疑问或评论,请访问我们的 Slack 或发送电子邮件至 hello@min.io。我们很乐意倾听你的意见。