在本教程中,您将了解如何使用 Cloudflare Pipelines、R2 Data Catalog 和 R2 SQL 构建完整的数据管道。这还包含一个示例 Python 脚本,该脚本创建并向您的 Pipeline 发送财务交易数据,这些数据可以由 R2 SQL 或任何与 Apache Iceberg 兼容的查询引擎进行查询。
本教程演示了如何:
- 设置 R2 Data Catalog 以将我们的交易事件存储在 Apache Iceberg 表中
- 设置 Cloudflare Pipeline
- 创建带有欺诈模式的交易数据以发送到您的 Pipeline
- 使用 R2 SQL 查询您的数据进行欺诈分析
- 注册一个 Cloudflare 账户 ↗。
- 安装 Node.js ↗。
- 为数据生成脚本安装 Python 3.8+ ↗。
您将需要 API 令牌来与 Cloudflare 服务进行交互。
-
在 Cloudflare 仪表板中,转到 API tokens(API 令牌) 页面。
Go to Account API tokens ↗ -
选择 Create Token(创建令牌)。
-
选择 Create Custom Token(创建自定义令牌) 旁边的 Get started(开始使用)。
-
输入 API 令牌的名称。
-
在 Permissions(权限) 下,选择:
- Workers Pipelines 具有 Read、Send 和 Edit 权限
- Workers R2 Data Catalog 具有 Read 和 Edit 权限
- Workers R2 SQL 具有 Read 权限
- Workers R2 Storage 具有 Read 和 Edit 权限
-
可选:向此令牌添加 TTL。
-
选择 Continue to summary(继续查看摘要)。
-
点击 Create Token(创建令牌)。
-
记下 Token value。
将您的新令牌导出为环境变量:
export WRANGLER_R2_SQL_AUTH_TOKEN= #在这里粘贴您的令牌如果这是您第一次使用 Wrangler,请确保登录。
npx wrangler login创建 R2 存储桶:
npx wrangler r2 bucket create fraud-pipeline-
在 Cloudflare 仪表板中,转到 R2 object storage(R2 对象存储) 页面。
Go to Overview ↗ -
选择 Create bucket(创建存储桶)。
-
输入存储桶名称:
fraud-pipeline -
选择 Create bucket(创建存储桶)。
在您的 R2 存储桶上启用目录:
npx wrangler r2 bucket catalog enable fraud-pipeline运行此命令时,请记下“Warehouse”和“Catalog URI”。您稍后将需要它们。
-
在 Cloudflare 仪表板中,转到 R2 object storage(R2 对象存储) 页面。
Go to Overview ↗ -
选择存储桶:
fraud-pipeline。 -
切换到 Settings(设置) 选项卡,向下滚动到 R2 Data Catalog,然后选择 Enable(启用)。
-
启用后,请记下 Catalog URI 和 Warehouse name。
export WAREHOUSE= #在这里粘贴您的 warehouseR2 Data Catalog 可以自动为您压缩表。在生产事件流用例中,通常会产生许多小文件,因此建议启用压缩。由于本教程仅演示示例用例,因此此步骤是可选的。
npx wrangler r2 bucket catalog compaction enable fraud-pipeline --token $WRANGLER_R2_SQL_AUTH_TOKEN-
在 Cloudflare 仪表板中,转到 R2 object storage(R2 对象存储) 页面。
Go to Overview ↗ -
选择存储桶:
fraud-pipeline。 -
切换到 Settings(设置) 选项卡,向下滚动到 R2 Data Catalog,点击编辑图标,然后选择 Enable(启用)。
-
您可以选择目标文件大小或保留默认值。点击保存。
首先,创建一个名为 raw_transactions_schema.json 的架构文件,其具有以下 json 架构:
{
"fields": [
{ "name": "transaction_id", "type": "string", "required": true },
{ "name": "user_id", "type": "int64", "required": true },
{ "name": "amount", "type": "float64", "required": false },
{ "name": "transaction_timestamp", "type": "string", "required": false },
{ "name": "location", "type": "string", "required": false },
{ "name": "merchant_category", "type": "string", "required": false },
{ "name": "is_fraud", "type": "bool", "required": false }
]
}创建一个流以接收传入的欺诈检测事件:
npx wrangler pipelines streams create raw_events_stream \
--schema-file raw_transactions_schema.json \
--http-enabled true \
--http-auth false# 来自输出的 http 摄取端点(请参阅以下示例)
export STREAM_ENDPOINT= #来自输出的 http 摄取端点(请参阅以下示例)输出应如下所示:
🌀 Creating stream 'raw_events_stream'...
✨ Successfully created stream 'raw_events_stream' with id 'stream_id'.
Creation Summary:
General:
Name: raw_events_stream
HTTP Ingest:
Enabled: Yes
Authentication: Yes
Endpoint: https://stream_id.ingest.cloudflare.com
CORS Origins: None
Input Schema:
┌───────────────────────┬────────┬────────────┬──────────┐
│ Field Name │ Type │ Unit/Items │ Required │
├───────────────────────┼────────┼────────────┼──────────┤
│ transaction_id │ string │ │ Yes │
├───────────────────────┼────────┼────────────┼──────────┤
│ user_id │ int64 │ │ Yes │
├───────────────────────┼────────┼────────────┼──────────┤
│ amount │float64 │ │ No │
├───────────────────────┼────────┼────────────┼──────────┤
│ transaction_timestamp │ string │ │ No │
├───────────────────────┼────────┼────────────┼──────────┤
│ location │ string │ │ No │
├───────────────────────┼────────┼────────────┼──────────┤
│ merchant_category │ string │ │ No │
├───────────────────────┼────────┼────────────┼──────────┤
│ is_fraud │ bool │ │ No │
└───────────────────────┴────────┴────────────┴──────────┘创建一个接收器,将数据作为 Apache Iceberg 表写入您的 R2 存储桶:
npx wrangler pipelines sinks create raw_events_sink \
--type "r2-data-catalog" \
--bucket "fraud-pipeline" \
--roll-interval 30 \
--namespace "fraud_detection" \
--table "transactions" \
--catalog-token $WRANGLER_R2_SQL_AUTH_TOKEN使用 SQL 将您的流连接到您的接收器:
npx wrangler pipelines create raw_events_pipeline \
--sql "INSERT INTO raw_events_sink SELECT * FROM raw_events_stream"-
在 Cloudflare 仪表板中,转到 Pipelines(管道) > Pipelines(管道)。
Go to Pipelines ↗ -
选择 Create Pipeline(创建管道)。
-
Connect to a Stream(连接到 Stream):
- Pipeline name(管道名称):
raw_events - Enable HTTP endpoint for sending data(启用用于发送数据的 HTTP 端点):已启用
- HTTP authentication(HTTP 身份验证):已禁用(默认)
- 选择 Next(下一步)
- Pipeline name(管道名称):
-
Define Input Schema(定义输入架构):
-
选择 JSON editor(JSON 编辑器)
-
复制架构:
{ "fields": [ { "name": "transaction_id", "type": "string", "required": true }, { "name": "user_id", "type": "int64", "required": true }, { "name": "amount", "type": "float64", "required": false }, { "name": "transaction_timestamp", "type": "string", "required": false }, { "name": "location", "type": "string", "required": false }, { "name": "merchant_category", "type": "string", "required": false }, { "name": "is_fraud", "type": "bool", "required": false } ] } -
选择 Next(下一步)
-
-
Define Sink(定义接收器):
- 选择您的 R2 存储桶:
fraud-pipeline - Storage type(存储类型):R2 Data Catalog
- Namespace(命名空间):
fraud_detection - Table name(表名称):
transactions - Advanced Settings(高级设置):将 Maximum Time Interval(最大时间间隔) 更改为
30 seconds - 选择 Next(下一步)
- 选择您的 R2 存储桶:
-
Credentials(凭据):
- 禁用 Automatically create an Account API token for your sink(自动为接收器创建账户 API 令牌)
- 从第 1 步输入 Catalog Token(目录令牌)
- 选择 Next(下一步)
-
Pipeline Definition(管道定义):
- 保留默认 SQL 查询:
INSERT INTO raw_events_sink SELECT * FROM raw_events_stream; - 选择 Create Pipeline(创建管道)
- 保留默认 SQL 查询:
-
创建管道后,请记下 Stream ID(流 ID) 以用于下一步。
创建一个 Python 脚本以生成带有欺诈模式的真实交易数据:
import requests
import json
import uuid
import random
import time
import os
from datetime import datetime, timezone, timedelta
# 配置 - 从之前的步骤中导出
STREAM_ENDPOINT = os.environ["STREAM_ENDPOINT"]# 来自您创建的流
API_TOKEN = os.environ["WRANGLER_R2_SQL_AUTH_TOKEN"] #前面创建的同一个
EVENTS_TO_SEND = 1000 # 随时调整它
def generate_transaction():
"""生成一些偶尔有欺诈的随机交易"""
# User IDs
high_risk_users = [1001, 1002, 1003, 1004, 1005]
normal_users = list(range(1006, 2000))
user_id = random.choice(high_risk_users + normal_users)
is_high_risk_user = user_id in high_risk_users
# 生成金额
if random.random() < 0.05:
amount = round(random.uniform(5000, 50000), 2)
elif random.random() < 0.03:
amount = round(random.uniform(0.01, 1.00), 2)
else:
amount = round(random.uniform(10, 500), 2)
# 地点
normal_locations = ["NEW_YORK", "LOS_ANGELES", "CHICAGO", "MIAMI", "SEATTLE", "SAN FRANCISCO"]
high_risk_locations = ["UNKNOWN_LOCATION", "VPN_EXIT", "MARS", "BAT_CAVE"]
if is_high_risk_user and random.random() < 0.3:
location = random.choice(high_risk_locations)
else:
location = random.choice(normal_locations)
# 商户类别
normal_merchants = ["GROCERY", "GAS_STATION", "RESTAURANT", "RETAIL"]
high_risk_merchants = ["GAMBLING", "CRYPTO", "MONEY_TRANSFER", "GIFT_CARDS"]
if random.random() < 0.1: # 10% 高风险商户
merchant_category = random.choice(high_risk_merchants)
else:
merchant_category = random.choice(normal_merchants)
# 一系列检查,用于按一定幅度增加欺诈评分
fraud_score = 0
if amount > 2000: fraud_score += 0.4
if amount < 1: fraud_score += 0.3
if location in high_risk_locations: fraud_score += 0.5
if merchant_category in high_risk_merchants: fraud_score += 0.3
if is_high_risk_user: fraud_score += 0.2
# 比较欺诈评分
is_fraud = random.random() < min(fraud_score * 0.3, 0.8)
# 生成时间戳(有些欺诈发生在不寻常的时间)
base_time = datetime.now(timezone.utc)
if is_fraud and random.random() < 0.4: # 40% 的欺诈在晚上
hour = random.randint(0, 5) # 深夜/清晨
transaction_time = base_time.replace(hour=hour)
else:
transaction_time = base_time - timedelta(
hours=random.randint(0, 168) # 上周
)
return {
"transaction_id": str(uuid.uuid4()),
"user_id": user_id,
"amount": amount,
"transaction_timestamp": transaction_time.isoformat(),
"location": location,
"merchant_category": merchant_category,
"is_fraud": True if is_fraud else False
}
def send_batch_to_stream(events, batch_size=100):
"""分批将事件发送到 Cloudflare Stream"""
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
total_sent = 0
fraud_count = 0
for i in range(0, len(events), batch_size):
batch = events[i:i + batch_size]
fraud_in_batch = sum(1 for event in batch if event["is_fraud"] == True)
try:
response = requests.post(STREAM_ENDPOINT, headers=headers, json=batch)
if response.status_code in [200, 201]:
total_sent += len(batch)
fraud_count += fraud_in_batch
print(f"Sent batch of {len(batch)} events (Total: {total_sent})")
else:
print(f"Failed to send batch: {response.status_code} - {response.text}")
except Exception as e:
print(f"Error sending batch: {e}")
time.sleep(0.1)
return total_sent, fraud_count
def main():
print("Generating fraud detection data...")
# 生成事件
events = []
for i in range(EVENTS_TO_SEND):
events.append(generate_transaction())
if (i + 1) % 100 == 0:
print(f"Generated {i + 1} events...")
fraud_events = sum(1 for event in events if event["is_fraud"] == True)
print(f"📊 Generated {len(events)} total events ({fraud_events} fraud, {fraud_events/len(events)*100:.1f}%)")
# 发送到流
print("Sending data to Pipeline stream...")
sent, fraud_sent = send_batch_to_stream(events)
print(f"\nComplete!")
print(f" Events sent: {sent:,}")
print(f" Fraud events: {fraud_sent:,} ({fraud_sent/sent*100:.1f}%)")
print(f" Data is now flowing through your pipeline!")
if __name__ == "__main__":
main()安装所需的 Python 依赖项并运行脚本:
pip install requests
python fraud_data_generator.py现在您可以使用 R2 SQL 分析您的欺诈检测数据。以下是一些示例查询:
npx wrangler r2 sql query "$WAREHOUSE" "
SELECT
transaction_id,
user_id,
amount,
location,
merchant_category,
is_fraud,
transaction_timestamp
FROM fraud_detection.transactions
WHERE __ingest_ts > '2025-09-24T01:00:00Z'
AND is_fraud = true
LIMIT 10"创建一个新的接收器,它将过滤后的数据写入 R2 Data Catalog 中的新 Apache Iceberg 表:
npx wrangler pipelines sinks create fraud_filter_sink \
--type "r2-data-catalog" \
--bucket "fraud-pipeline" \
--roll-interval 30 \
--namespace "fraud_detection" \
--table "fraud_transactions" \
--catalog-token $WRANGLER_R2_SQL_AUTH_TOKEN现在,您将创建一个新的 SQL 查询来处理来自原始 raw_events_stream 流的数据,并且只写入标记为欺诈且 amount 大于 1,000 的交易。
npx wrangler pipelines create fraud_events_pipeline \
--sql "INSERT INTO fraud_filter_sink SELECT * FROM raw_events_stream WHERE is_fraud=true and amount > 1000"查询表并检查结果:
npx wrangler r2 sql query "$WAREHOUSE" "
SELECT
transaction_id,
user_id,
amount,
location,
merchant_category,
is_fraud,
transaction_timestamp
FROM fraud_detection.fraud_transactions
LIMIT 10"还要验证是否正在过滤掉非欺诈性事件:
npx wrangler r2 sql query "$WAREHOUSE" "
SELECT
transaction_id,
user_id,
amount,
location,
merchant_category,
is_fraud,
transaction_timestamp
FROM fraud_detection.fraud_transactions
WHERE is_fraud = false
LIMIT 10"您应该看到以下输出:
Query executed successfully with no results您已成功使用 Cloudflare 的数据平台构建了端到端数据管道。通过本教程,您学会了:
- 使用 R2 Data Catalog:利用 Apache Iceberg 表实现高效的数据存储
- 设置 Cloudflare Pipelines:为数据摄取创建了流、接收器和管道
- 生成示例数据:创建了带有一些基本欺诈模式的交易数据
- 使用 R2 SQL 查询您的表:访问存储在 R2 Data Catalog 中的原始和已处理数据表