Documentation

使用 Quix Streams 来下采样数据

使用 Quix Streams 查询存储在 InfluxDB 中的时间序列数据,并定期写入 Kafka,持续对其进行降采样,然后将降采样的数据写回 InfluxDB。Quix Streams 是一个开源的 Python 库,用于构建容器化的流处理应用程序,使用 Apache Kafka。它被设计为作为一个服务运行,持续处理数据流,同时将结果流式传输到 Kafka 主题。您可以在本地尝试,使用本地 Kafka 安装,或在 Quix Cloud 上运行试用。

本指南使用 PythonInfluxDB 3 Python client library,但您可以使用您选择的运行时和任何可用的 InfluxDB 3 client libraries。本指南还假设您已经 setup your Python project and virtual environment

管道架构

下图展示了数据在被降采样时如何在进程之间传递:

InfluxDB v3 源生产者

下采样过程

InfluxDB v3 吸 Sink 消费者

通常直接将原始数据写入Kafka比先将原始数据写入InfluxDB更加高效(本质上是用“raw-data”主题开始Quix Streams管道)。然而,本指南假设您已经在InfluxDB中有原始数据需要进行降采样。


  1. 设置前提条件
  2. 安装依赖
  3. 准备InfluxDB桶
  4. 创建下采样逻辑
  5. 创建生产者和消费者客户端
    1. 创建生产者
    2. 创建消费者
  6. 获取完整的下采样代码文件

设置前提条件

本指南中描述的过程需要以下内容:

  • 一个准备好进行降采样的 InfluxDB Cloud Serverless 账号。
  • 一个 Quix Cloud 账户或本地的 Apache Kafka 或 Red Panda 安装。
  • 熟悉基本的Python和Docker概念。

安装依赖

使用 pip 安装以下依赖项:

  • influxdb_client_3
  • quixstreams<2.5
  • pandas
pip install influxdb3-python pandas quixstreams<2.5

准备InfluxDB桶

降采样过程涉及两个 InfluxDB 存储桶。 每个存储桶都有一个 保留期,指定数据在过期并被删除之前持续多久。 通过使用两个存储桶,您可以在保留期较短的存储桶中存储未修改的高分辨率数据,然后在保留期较长的存储桶中存储降采样的低分辨率数据。

确保您为以下每一项准备一个桶:

  • 从中查询未修改的数据
  • 另一个用于写入下采样数据的

有关创建存储桶的信息,请参见 创建存储桶

创建下采样逻辑

此过程从输入的Kafka主题读取原始数据,该主题存储从InfluxDB流式传输的数据,进行下采样,然后将其发送到一个输出主题,该主题用于写回InfluxDB。

  1. 使用Quix Streams库的 Application 类来初始化与Apache Kafka的连接。

    from quixstreams import Application
    
    app = Application(consumer_group='downsampling-process', auto_offset_reset='earliest')
    input_topic = app.topic('raw-data')
    output_topic = app.topic('downsampled-data')
    
    # ...
    
  2. 配置Quix Streams内置窗口函数,以创建一个持续将数据下采样到1分钟桶的翻滚窗口。

    # ...
    target_field = 'temperature' # The field that you want to downsample.
    
    def custom_ts_extractor(value):
        # ...
        # truncated for brevity - custom code that defines the 'time_recorded'
        # field as the timestamp to use for windowing...
    
    topic = app.topic(input_topic, timestamp_extractor=custom_ts_extractor)
    
    sdf = (
        sdf.apply(lambda value: value[target_field])  # Extract temperature values
        .tumbling_window(timedelta(minutes=1))   # 1-minute tumbling windows
        .mean()                                  # Calculate average temperature
        .final()                                 # Emit results at window completion
    )
    
    sdf = sdf.apply(
        lambda value: {
            'time': value['end'],                  # End of the window
            'temperature_avg': value['value'],     # Average temperature
        }
    )
    
    sdf.to_topic(output_topic) # Output results to the 'downsampled-data' topic
    # ...
    

结果被流式传输到 Kafka 主题,downsampled-data

注意:“sdf”代表“流式数据框”。

您可以在Quix GitHub repository中找到此过程的完整代码。

创建生产者和消费者客户端

使用 influxdb_client_3quixstreams 模块实例化两个与 InfluxDB 和 Apache Kafka 交互的客户端:

  • A producer client configured to read from your InfluxDB bucket with 未修改的 data and 生成 that data to Kafka.
  • 一个消费者客户端,被配置为消费来自Kafka的数据并将降采样的数据写入相应的InfluxDB桶。

创建生产者客户端

提供以下制片人的凭证:

  • host: InfluxDB Cloud Serverless 区域 URL (不带协议)
  • org: InfluxDB 组织名称
  • token: InfluxDB API 令牌,具有对您想要查询和写入的存储桶的读写权限。
  • database: InfluxDB 桶名称

生产者在特定的时间间隔内从InfluxDB查询新数据。它被配置为查找在变量中定义的特定测量。它将原始数据写入名为‘raw-data’的Kafka主题

from influxdb_client_3 import InfluxDBClient3
from quixstreams import Application
import pandas

# Instantiate an InfluxDBClient3 client configured for your unmodified bucket
influxdb_raw = InfluxDBClient3(
    host='cloud2.influxdata.com',
    token='
API_TOKEN
'
,
database='
RAW_BUCKET_NAME
'
) # os.environ['localdev'] = 'true' # Uncomment if you're using local Kafka rather than Quix Cloud # Create a Quix Streams producer application that connects to a local Kafka installation app = Application( broker_address=os.environ.get('BROKER_ADDRESS','localhost:9092'), consumer_group=consumer_group_name, auto_create_topics=True ) # Override the app variable if the local development env var is set to false or is not present. # This causes Quix Streams to use an application configured for Quix Cloud localdev = os.environ.get('localdev', 'false') if localdev == 'false': # Create a Quix platform-specific application instead (broker address is in-built) app = Application(consumer_group=consumer_group_name, auto_create_topics=True) topic = app.topic(name='raw-data') ## ... remaining code trunctated for brevity ... # Query InfluxDB for the raw data and store it in a Dataframe def get_data(): # Run in a loop until the main thread is terminated while run: try: myquery = f'SELECT * FROM "{measurement_name}" WHERE time >= {interval}' print(f'sending query {myquery}') # Query InfluxDB 3 using influxql or sql table = influxdb_raw.query( query=myquery, mode='pandas', language='influxql') #... remaining code trunctated for brevity ... # Send the data to a Kafka topic for the downsampling process to consumer def main(): """ Read data from the Query and publish it to Kafka """ #... remaining code trunctated for brevity ... for index, obj in enumerate(records): print(obj) # Obj contains each row in the table includimng temperature # Generate a unique message_key for each row message_key = obj['machineId'] logger.info(f'Produced message with key:{message_key}, value:{obj}') serialized = topic.serialize( key=message_key, value=obj, headers={'uuid': str(uuid.uuid4())} ) # publish each row returned in the query to the topic 'raw-data' producer.produce( topic=topic.name, headers=serialized.headers, key=serialized.key, value=serialized.value, )

您可以在Quix GitHub repository中找到此过程的完整代码。

创建消费者

与之前一样,为消费者提供以下凭据:

  • host: InfluxDB Cloud Serverless 区域 URL (不带协议)
  • org: InfluxDB 组织名称
  • token: InfluxDB API 令牌,具有对您想要查询和写入的存储桶的读取和写入权限。
  • database: InfluxDB 桶名称

该过程从Kafka主题 downsampled-data 读取消息,并将每条消息作为点字典写回InfluxDB。

# Instantiate an InfluxDBClient3 client configured for your downsampled database.
# When writing, the org= argument is required by the client (but ignored by InfluxDB).
influxdb_downsampled = InfluxDBClient3(
    host='cloud2.influxdata.com',
    token='
API_TOKEN
'
,
database='
DOWNSAMPLED_BUCKET_NAME
'
,
org='' ) # os.environ['localdev'] = 'true' # Uncomment if you're using local Kafka rather than Quix Cloud # Create a Quix Streams consumer application that connects to a local Kafka installation app = Application( broker_address=os.environ.get('BROKER_ADDRESS','localhost:9092'), consumer_group=consumer_group_name, auto_create_topics=True ) # Override the app variable if the local development env var is set to false or is not present. # This causes Quix Streams to use an application configured for Quix Cloud localdev = os.environ.get('localdev', 'false') if localdev == 'false': # Create a Quix platform-specific application instead (broker address is in-built) app = Application(consumer_group=consumer_group_name, auto_create_topics=True) input_topic = app.topic('downsampled-data') ## ... remaining code trunctated for brevity ... def send_data_to_influx(message): logger.info(f'Processing message: {message}') try: ## ... remaining code trunctated for brevity ... # Construct the points dictionary points = { 'measurement': measurement_name, 'tags': tags, 'fields': fields, 'time': message['time'] } influxdb_downsampled.write(record=points, write_precision='ms') sdf = app.dataframe(input_topic) sdf = sdf.update(send_data_to_influx) # Continuously apply the 'send_data' function to each message in the incoming stream ## ... remaining code trunctated for brevity ...

您可以在Quix GitHub repository中找到此过程的完整代码。

获取完整的下采样代码文件

要获取本教程中引用的完整文件集,请克隆 Quix 的“降采样模板”代码库,或使用保存为 Jupyter Notebook 的本教程的交互版本。

克隆降采样模板库

要克隆下采样模板,请在命令行中输入以下命令:

git clone https://github.com/quixio/template-influxdbv3-downsampling.git

该仓库包含以下文件夹,存储整个流程的不同部分:

  • 机器数据到 InfluxDB: 一个生成合成机器数据并将其写入 InfluxDB 的脚本。这在您还没有自己的数据,或者只想先使用测试数据时非常有用。

    • It produces a reading every 250 milliseconds.
    • This script originally comes from the InfluxCommunity repository but has been adapted to write directly to InfluxDB rather than using an MQTT broker.
  • InfluxDB V3 数据源: 一项定期从 InfluxDB 查询新数据的服务。它被配置为查找之前提到的合成机器数据生成器产生的测量值。它将原始数据写入名为“raw-data”的 Kafka 主题。

  • 下采样器: 一项服务,在来自InfluxDB的数据上执行1分钟的滚动窗口操作,并每分钟发出“温度”读数的平均值。它将输出写入“下采样数据”Kafka主题。

  • InfluxDB V3 数据接收器: 一个从“降采样数据”主题读取并将降采样记录作为点写回到 InfluxDB 的服务。

使用下采样的Jupyter笔记本

您可以使用交互式笔记本 “使用 InfluxDB 和 Quix Streams 持续下采样数据” 来尝试自己进行下采样代码。它配置为在运行时环境中安装 Apache Kafka(例如 Google Colab)。

每个进程也被设置为在后台运行,以便一个正在运行的单元不会阻塞其余的教程。

Open In Colab



Flux的未来

Flux 正在进入维护模式。您可以像现在一样继续使用它,而无需对您的代码进行任何更改。

阅读更多

InfluxDB 3 开源版本现已公开Alpha测试

InfluxDB 3 Open Source is now available for alpha testing, licensed under MIT or Apache 2 licensing.

我们将发布两个产品作为测试版的一部分。

InfluxDB 3 核心,是我们新的开源产品。 它是一个用于时间序列和事件数据的实时数据引擎。 InfluxDB 3 企业版是建立在核心基础之上的商业版本,增加了历史查询能力、读取副本、高可用性、可扩展性和细粒度安全性。

有关如何开始的更多信息,请查看:

InfluxDB 云端无服务器