INTEGRITY Документация

Создание сквозного пайплайна данных

В этом руководстве вы узнаете, как построить полноценный пайплайн данных с помощью Cloudflare Pipelines, R2 Data Catalog и R2 SQL. Вы также найдёте пример скрипта на Python, который создаёт и отправляет данные о финансовых транзакциях в ваш Pipeline, доступный для запросов через R2 SQL или любой другой движок запросов, совместимый с Apache Iceberg.

В этом руководстве вы узнаете, как:

Предварительные требования

  1. Зарегистрируйтесь для получения Аккаунт Cloudflare ↗.
  2. Установка Node.js ↗.
  3. Установка Python 3.8+ ↗ для скрипта генерации данных.

1. Настройте аутентификацию

Для взаимодействия с сервисами Cloudflare вам понадобятся API токены.

  1. На панели управления Cloudflare перейдите к разделу API-токены страницу.

    Перейдите в Токены API аккаунта ↗
  2. Выберите Create Token.

  3. Выберите Начало работы рядом с Create Custom Token.

  4. Введите имя для токена API.

  5. В разделе Разрешения, выберите:

    • Workers Pipelines с правами Read, Send и Edit
    • Workers R2 Data Catalog с правами Read и Edit
    • Workers R2 SQL с правами Read
    • Workers R2 Storage с правами Read и Edit
  6. При необходимости добавьте к этому токену TTL.

  7. Выберите Continue to summary.

  8. Нажмите Create Token

  9. Обратите внимание на Значение токена.

Экспортируйте новый токен в переменную окружения:

export WRANGLER_R2_SQL_AUTH_TOKEN= #paste your token here

Если вы используете Wrangler впервые, обязательно выполните вход.

npx wrangler login

2. Создайте bucket R2 и включите R2 Data Catalog

Создайте бакет R2:

npx wrangler r2 bucket create fraud-pipeline
  1. На панели управления Cloudflare перейдите к разделу Объектное хранилище R2 страницу.

    Перейдите в Обзор ↗
  2. Выберите Создание бакета.

  3. Введите имя бакета: fraud-pipeline

  4. Выберите Создание бакета.

Включите каталог для своего бакета R2:

npx wrangler r2 bucket catalog enable fraud-pipeline

При выполнении этой команды запишите значения "Warehouse" и "Catalog URI". Они понадобятся вам позже.

  1. На панели управления Cloudflare перейдите к разделу Объектное хранилище R2 страницу.

    Перейдите в Обзор ↗
  2. Выберите бакет: fraud-pipeline.

  3. Перейдите на вкладку Настройки вкладку и прокрутите вниз до R2 Data Catalog, и выберите Включить.

  4. После включения обратите внимание на Catalog URI и Имя хранилища.

export WAREHOUSE= #Paste your warehouse here

(Необязательно) Включите компактизацию в своём R2 Data Catalog

R2 Data Catalog умеет автоматически уплотнять таблицы. В боевых сценариях потоковой передачи событий часто накапливается много мелких файлов, поэтому уплотнение рекомендуется включить. Поскольку это руководство демонстрирует лишь тестовый сценарий, данный шаг необязателен.

npx wrangler r2 bucket catalog compaction enable fraud-pipeline --token $WRANGLER_R2_SQL_AUTH_TOKEN
  1. На панели управления Cloudflare перейдите к разделу Объектное хранилище R2 страницу.

    Перейдите в Обзор ↗
  2. Выберите бакет: fraud-pipeline.

  3. Перейдите на вкладку Настройки вкладку и прокрутите вниз до R2 Data Catalog, нажмите на значок редактирования и выберите Включить.

  4. Вы можете выбрать целевой размер файла или оставить значение по умолчанию. Нажмите «Сохранить».

3. Настройте инфраструктуру pipeline

3.1. Создайте Pipeline stream

Сначала создайте файл схемы с именем 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
# The http ingest endpoint from the output (see example below)
export STREAM_ENDPOINT= #the http ingest endpoint from the output (see example below)

Результат должен выглядеть следующим образом:

🌀 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       │
└───────────────────────┴────────┴────────────┴──────────┘

3.2. Создайте data sink

Создайте приёмник, который записывает данные в ваш бакет R2 в виде таблиц Apache Iceberg:

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

3.3. Создайте pipeline

Подключите поток к приёмнику с помощью SQL:

npx wrangler pipelines create raw_events_pipeline \
  --sql "INSERT INTO raw_events_sink SELECT * FROM raw_events_stream"
  1. В панели управления Cloudflare перейдите в Pipelines > Pipelines.

    Перейдите в Pipelines ↗
  2. Выберите Create Pipeline.

  3. Подключение к Stream:

    • Имя конвейера: raw_events
    • Включить HTTP-эндпоинт для отправки данных: Enabled
    • HTTP authentication: Disabled (default)
    • Выберите Далее
  4. Define Input Schema:

    • Выберите Редактор 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 }
      	]
      }
    • Выберите Далее

  5. Define Sink:

    • Выберите свой бакет R2: fraud-pipeline
    • Тип хранилища: R2 Data Catalog
    • Пространство имён: fraud_detection
    • Имя таблицы: transactions
    • Дополнительные настройки: Изменение Максимальный интервал времени к 30 seconds
    • Выберите Далее
  6. Учётные данные:

    • Отключить Автоматически создать Account API token для вашего sink
    • Введите Catalog Token из шага 1
    • Выберите Далее
  7. Определение конвейера:

    • Оставьте SQL-запрос по умолчанию:
      INSERT INTO raw_events_sink SELECT * FROM raw_events_stream;
    • Выберите Create Pipeline
  8. После создания pipeline запомните ID потока для следующего шага.

4. Сгенерируйте тестовые данные для обнаружения мошенничества

Создайте Python-скрипт для генерации реалистичных данных о транзакциях с признаками мошенничества:

fraud_data_generator.py
import requests
import json
import uuid
import random
import time
import os
from datetime import datetime, timezone, timedelta

# Configuration - exported from the prior steps
STREAM_ENDPOINT = os.environ["STREAM_ENDPOINT"]# From the stream you created
API_TOKEN = os.environ["WRANGLER_R2_SQL_AUTH_TOKEN"] #the same one created earlier
EVENTS_TO_SEND = 1000 # Feel free to adjust this

def generate_transaction():
    """Generate some random transactions with occasional fraud"""

    # 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

    # Generate amounts
    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)

    # Locations
    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)

    # Merchant categories
    normal_merchants = ["GROCERY", "GAS_STATION", "RESTAURANT", "RETAIL"]
    high_risk_merchants = ["GAMBLING", "CRYPTO", "MONEY_TRANSFER", "GIFT_CARDS"]

    if random.random() < 0.1:  # 10% high-risk merchants
        merchant_category = random.choice(high_risk_merchants)
    else:
        merchant_category = random.choice(normal_merchants)

    # Series of checks to either increase fraud score by a certain margin
    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

    # Compare the fraud scores
    is_fraud = random.random() < min(fraud_score * 0.3, 0.8)

    # Generate timestamps (some fraud happens at unusual hours)
    base_time = datetime.now(timezone.utc)
    if is_fraud and random.random() < 0.4:  # 40% of fraud at night
        hour = random.randint(0, 5)  # Late night/early morning
        transaction_time = base_time.replace(hour=hour)
    else:
        transaction_time = base_time - timedelta(
            hours=random.randint(0, 168)  # Last week
        )

    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):
    """Send events to Cloudflare Stream in batches"""

    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...")

    # Generate events
    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}%)")

    # Send to stream
    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

5. Запросите данные с помощью R2 SQL

Теперь вы можете анализировать данные обнаружения мошенничества с помощью R2 SQL. Вот несколько примеров запросов:

5.1. Просмотрите последние транзакции

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"

5.2. Отфильтруйте необработанные транзакции в новую таблицу, чтобы выделить транзакции с высокой суммой

Создайте новый приёмник, который будет записывать отфильтрованные данные в новую таблицу Apache Iceberg в R2 Data Catalog:

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. В этом руководстве вы научились:

  1. Используйте R2 Data Catalog: Использовал таблицы Apache Iceberg для эффективного хранения данных
  2. Настроить Cloudflare Pipelines: Создал потоки, приёмники и пайплайны для приёма данных
  3. Сгенерированные примеры данных: Создал транзакционные данные с несколькими базовыми шаблонами мошенничества
  4. Запрос таблиц с помощью R2 SQL: доступ к необработанным и обработанным таблицам данных, хранящимся в R2 Data Catalog