使用 Kafka 和 MinIO 实现人工智能数据工作流

MinIO Enterprise Object Store 是用于创建和执行复杂数据工作流的基础组件。此事件驱动功能的核心是使用 Kafka 的 MinIO 存储桶通知。MinIO Enterprise Object Store 为所有 HTTP 请求(如 PUT、POST、COPY、DELETE、GET、HEAD 和 CompleteMultipartUpload)生成事件通知。您可以使用这些通知来触发相应的应用程序、脚本和 Lambda 函数,以便在对象上传触发事件通知后执行操作。事件通知为多个微服务提供了一个松散耦合的范例,用于交互和协作。在此范例中,微服务不会相互直接调用,而是使用事件通知进行通信。发送通知后,发送服务可以返回到其任务,而接收服务则执行操作。这种级别的隔离使维护代码变得更加容易 — 更改一项服务不需要更改其他服务,因为它们通过通知而不是直接调用进行通信。有几个用例依赖于 MinIO Enterprise Object Store 事件通知来执行数据工作流。例如,我们可以使用将存储在 MinIO Enterprise Object Store 中的对象的原始数据运行 AI/ML 管道。

  • 每当添加原始对象时,都会触发处理数据的管道

  • 根据添加的对象,模型将运行。

  • 最终模型可以保存到 MinIO Enterprise Object Store 中的存储桶中,然后其他应用程序可以将其作为最终产品使用。

构建工作流程

我们将使用 MinIO Enterprise Object Store 和 Kafka 为假设的图像调整器应用程序构建一个示例工作流。它本质上是获取传入的图像并根据某些应用程序规范调整它们的大小,然后将它们保存到另一个可以投放它们的存储桶中。在现实世界中,这可能是为了调整图像大小并使其可供移动应用程序使用,或者只是调整图像大小以减轻动态调整图像大小时对资源的压力。它有几个组件,Kafka 和 MinIO Enterprise Object Store 一起使用来支持这个复杂的工作流程

  • MinIOEnterprise Object Store,创建者:传入的原始对象存储在 MinIO Enterprise Object Store 中。每当添加对象时,它都会向 Kafka 发送消息以代理特定主题。

  • Kafka,代理:代理维护队列的状态,存储传入消息,并使其可供使用者使用。

  • MinIO Enterprise Object Store,使用者:使用者将在队列中读取此消息,因为它们实时进入,处理原始数据,并将其上传到 MinIO Enterprise Object Store 存储桶。

MinIO Enterprise Object Store 是这一切的基础,因为它是此工作流的生产者和使用者。

使用 Kubernetes 集群

我们需要一个 Kubernetes 集群来运行我们的服务。您可以使用任何 Kubernetes 集群,但在此示例中,我们将使用 kind 集群。如果尚未安装 Kind,请按照此快速入门指南中的说明进行操作。使用以下类型的集群配置来构建具有多工作线程 Kubernetes 集群的简单单个 master。将此 yaml 保存为 kind-config.yaml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker

启动集群(这可能需要几分钟时间)

$ kind create cluster --name minio-kafka --config kind-config.yaml… [truncated]Set kubectl context to "kind-minio-kafka"
You can now use your cluster with:kubectl cluster-info --context kind-minio-kafka… [truncated]

验证集群是否已启动

$ kubectl get no
NAME                        STATUS   ROLES           AGE   VERSION
minio-kafka-control-plane   Ready    control-plane   43s   v1.24.0
minio-kafka-worker          Ready    <none>          21s   v1.24.0
minio-kafka-worker2         Ready    <none>          21s   v1.24.0
minio-kafka-worker3         Ready    <none>          21s   v1.24.0

安装 Kafka

Kafka 需要运行一些服务来支持它,然后才能运行。这些服务是:

  • 证书

  • 动物园管理员

让我们在 Kubernetes 集群中安装 cert-manager

$ kubectl create -f https://github.com/jetstack/cert-manager/releases/download/v1.6.2/cert-manager.yaml

检查状态以验证是否已创建 cert-manager 资源

$ kubectl get ns
NAME                 STATUS   AGE
cert-manager         Active   6s
default              Active   20m
kube-node-lease      Active   20m
kube-public          Active   20m
kube-system          Active   20m
local-path-storage   Active   20m$ kubectl get po -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-74f9fd7fb6-kqhsq              1/1     Running   0          14s
cert-manager-cainjector-67977b8fcc-k49gj   1/1     Running   0          14s
cert-manager-webhook-7ff8d87f4-wg94l       1/1     Running   0          14s

使用 Helm 图表安装 zookeeper。如果您尚未安装 helm,可以按照 helm 文档中的安装指南进行操作。

$ helm repo add pravega https://charts.pravega.io
"pravega" has been added to your repositories$ helm repo update$ helm install zookeeper-operator --namespace=zookeeper --create-namespace pravega/zookeeper-operator… [truncated]$ kubectl --namespace zookeeper create -f - <<EOF
apiVersion: zookeeper.pravega.io/v1beta1
kind: ZookeeperCluster
metadata:name: zookeepernamespace: zookeeper
spec:replicas: 1
EOF

您应该会看到与此类似的输出,这意味着集群创建正在进行中。

zookeepercluster.zookeeper.pravega.io/zookeeper created

验证 zookeeper 操作员和集群 Pod 是否都在运行

$ kubectl -n zookeeper get po
NAME                                  READY   STATUS    RESTARTS   AGE
zookeeper-0                           1/1     Running   0          31s
zookeeper-operator-5857967dcc-kfxxt   1/1     Running   0          3m4s

现在我们已经解决了所有先决条件,让我们安装实际的 Kafka 集群组件。Kafka 有一个名为 Koperator 的 Operator,我们将使用它来管理 Kafka 安装。Kafka 集群大约需要 4-5 分钟才能启动。

$ kubectl create --validate=false -f https://github.com/banzaicloud/koperator/releases/download/v0.21.2/kafka-operator.crds.yaml$ helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com/$ helm repo update
… [truncated]$ helm install kafka-operator --namespace=kafka --create-namespace banzaicloud-stable/kafka-operator… [truncated]$ kubectl create -n kafka -f https://raw.githubusercontent.com/banzaicloud/koperator/master/config/samples/simplekafkacluster.yaml

执行 kubectl -n kafka get po 确认 Kafka 已启动。Kafka 需要几分钟时间才能运行。请稍候,然后再继续。

配置 Kafka 主题

让我们先配置 Topic,然后再在 MinIO 中配置它;该主题是先决条件。

创建名为 my-topic 的主题

$ kubectl apply -n kafka -f - <<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:name: my-topic
spec:clusterRef:name: kafkaname: my-topicpartitions: 1replicationFactor: 1config:"retention.ms": "604800000""cleanup.policy": "delete"
EOF

它应返回以下输出。否则,主题创建不成功。如果不成功,请等待几分钟,让 Kafka 集群联机,然后再次重新运行它。

kafkatopic.kafka.banzaicloud.io/my-topic created

在接下来的几个步骤中,我们需要一个 Kafka Pod 的 IP 和端口

要获取 IP,请执行以下操作:

$ kubectl -n kafka describe po kafka-0- | grep -i IP:
IP:           10.244.1.5IP:           10.244.1.5

注意:您的 IP 会有所不同,并且可能与上述 IP 不匹配。我们感兴趣的是几个端口

$ kubectl -n kafka get po kafka-0- -o yaml | grep -iA1 containerport- containerPort: 29092name: tcp-internal
--- containerPort: 29093name: tcp-controller… [truncated]
  • tcp-internal 29092:当您作为使用者处理传入到 Kafka 集群的消息时,使用此端口。

  • tcp-controller 29093:这是当生产者(如 MinIO)想要向 Kafka 集群发送消息时使用的端口。

这些 IP 和端口可能会在您自己的设置中发生变化,因此请务必为您的集群获取正确的值。

安装 MinIO

我们将 MinIO 安装在与其他资源相同的 Kubernetes 集群中其自己的命名空间中。获取 MinIO 存储库

$ git clone https://github.com/minio/operator.git

应用资源以安装 MinIO

$ kubectl apply -k operator/resources$ kubectl apply -k operator/examples/kustomization/tenant-lite

验证 MinIO 是否已启动并正在运行。您可以获取 MinIO 控制台的端口,在本例中为 9443。

$ kubectl -n tenant-lite get svc | grep -i consolestorage-lite-console             ClusterIP   10.96.0.215     <none>        9443/TCP   6m53s

设置 kubernetes 端口转发:我们在这里为主机选择了端口 39443,但这可以是任何东西,只需确保在通过 Web 浏览器访问控制台时使用相同的端口。

$ kubectl -n tenant-lite port-forward svc/storage-lite-console 39443:9443Forwarding from 127.0.0.1:39443 -> 9443Forwarding from [::1]:39443 -> 9443

使用以下凭证通过 Web 浏览器访问

网址:https://localhost:39443

用户: minio

通行证: minio123

配置 MinIO 生产者

我们将配置 MinIO 以将事件发送到我们之前使用 mc 管理工具创建的 Kafka 集群中的 my-topic。我在这里启动了一个 Ubuntu Pod,这样我就有一个干净的工作区可以工作,更重要的是,我可以访问集群中的所有 Pod,而无需将每个单独的服务端口转发。

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:name: ubuntulabels:app: ubuntu
spec:containers:- image: ubuntucommand:- "sleep"- "604800"imagePullPolicy: IfNotPresentname: ubunturestartPolicy: Always
EOF

shell 放入 Ubuntu Pod 中,以确保其已启动

$ kubectl exec -it ubuntu -- /bin/bashroot@ubuntu:/#

如果您看到任何前缀为 root@ubuntu:/ 的命令,则表示它正在此 ubuntu pod 中运行。使用以下命令获取 mc 二进制文件并安装

root@ubuntu:/# apt-get update
apt-get -y install wget
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
mv mc /usr/local/bin/

验证是否已正确安装

root@ubuntu:/# mc --versionmc version RELEASE.2022-08-05T08-01-28Z (commit-id=351d021b924b4d19f1eb716b9e2bd74644c402d8)Runtime: go1.18.5 linux/amd64Copyright (c) 2015-2022 MinIO, Inc.License GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>

配置 mc admin 以使用我们的 MinIO 集群

  • mc alias set <alias_name> <minio_tenant_url> <minio_username> <minio_password>

在我们的例子中,这将转化为

root@ubuntu:/# mc alias set myminio https://minio.tenant-lite.svc.cluster.local minio minio123Added `myminio` successfully.

通过运行以下命令验证配置是否按预期工作;您应该会看到类似于 8 drives online, 0 drives offline

root@ubuntu:/# mc admin info myminio… [truncated]Pools:1st, Erasure sets: 1, Disks per erasure set: 88 drives online, 0 drives offline

通过 mc admin 在 MinIO 中设置 Kafka 配置。您需要使用

root@ubuntu:/# mc admin config set myminio \
notify_kafka:1 \
brokers="10.244.1.5:29093" \
topic="my-topic" \
tls_skip_verify="off" \
queue_dir="" \
queue_limit="0" \
sasl="off" \
sasl_password="" \
sasl_username="" \
tls_client_auth="0" \
tls="off" \
client_tls_cert="" \
client_tls_key="" \
version="" --insecure

您必须特别注意其中一些配置

  • brokers=“10.244.1.5:29093”:这些是格式 server1:port1,server2:port2,serverN:portN 为 .注意:如果你决定提供多个 Kafka 服务器,你需要提供所有服务器的 IP;如果你给出一个部分列表,它将失败。你可以提供单个服务器,但缺点是如果该服务器宕机,则配置将不知道集群中的其他 Kafka 服务器。正如我们之前提到的,有两个端口:TCP 内部 29092 和 TCP 控制器 29093。由于我们将 MinIO 配置为 Producer,因此我们将使用 29093。

  • topic=“my-topic”:主题名称应与我们之前在 Kafka 集群中创建的主题匹配。提醒一下,MinIO 不会自动创建此主题;它必须事先可用。

  • notify_kafka:1:这是稍后将用于实际添加事件的配置名称。

有关这些参数的更多详细信息,请访问我们的文档。成功后,您应该会看到下面的输出

Successfully applied new settings.

根据需要,让我们重新启动 admin 服务

root@ubuntu:/# mc admin service restart myminioRestart command successfully sent to `myminio`. Type Ctrl-C to quit or wait to follow the status of the restart process.....Restarted `myminio` successfully in 2 seconds

在 MinIO 中创建一个名为 images 的存储桶。这是 Raw 对象将存储的位置。

root@ubuntu:/# mc mb myminio/images --insecureBucket created successfully `myminio/images`.

我们希望将发送到队列的消息限制为仅.jpg图像;这可以根据需要进行扩展,例如,如果要将消息设置为基于其他文件扩展名(如 .png)触发。

root@ubuntu:/# mc event add  myminio/images arn:minio:sqs::1:kafka --suffix .jpgSuccessfully added arn:minio:sqs::1:kafka# Verify it has been added properly
root@ubuntu:/# mc event list myminio/imagesarn:minio:sqs::1:kafka   s3:ObjectCreated:*,s3:ObjectRemoved:*,s3:ObjectAccessed:*   Filter: suffix=".jpg"

有关如何使用 MinIO 配置 Kafka 的更多详细信息,请访问我们的文档。

构建 MinIO 使用者

如果我们真的有一个脚本,可以使用由 MinIO 生成的这些事件并对这些对象执行一些操作,那就太酷了。那么为什么不这样做呢?这样,我们就可以全面了解工作流程。在仍然登录到我们的 ubuntu pod 时,安装 python3 和 python3-pip 以运行我们的脚本。由于这是 Ubuntu 的最小版本,我们还需要 vim 来编辑我们的脚本。

root@ubuntu:/# apt-get -y install python3 python3-pip vim

对于我们的 Python 使用者脚本,我们需要通过 pip 安装一些 Python 包

root@ubuntu:/# pip3 install minio kafka-pythonCollecting minioDownloading minio-7.1.11-py3-none-any.whl (76 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 76.1/76.1 KB 4.1 MB/s eta 0:00:00Collecting kafka-pythonDownloading kafka_python-2.0.2-py2.py3-none-any.whl (246 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 246.5/246.5 KB 8.6 MB/s eta 0:00:00Collecting certifiDownloading certifi-2022.6.15-py3-none-any.whl (160 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.2/160.2 KB 11.6 MB/s eta 0:00:00Collecting urllib3Downloading urllib3-1.26.11-py2.py3-none-any.whl (139 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 139.9/139.9 KB 18.4 MB/s eta 0:00:00Installing collected packages: kafka-python, urllib3, certifi, minioSuccessfully installed certifi-2022.6.15 kafka-python-2.0.2 minio-7.1.11 urllib3-1.26.11

如果您看到上述消息,则表示我们已成功安装脚本所需的依赖项。我们将在此处显示整个脚本,然后引导您了解正在运行的不同组件。现在,将此脚本另存为 minio_consumer.py

from minio import Minio
import urllib3from kafka import KafkaConsumer
import json# Convenient dict for basic config
config = {"dest_bucket":    "processed", # This will be auto created"minio_endpoint": "minio.tenant-lite.svc.cluster.local","minio_username": "minio","minio_password": "minio123","kafka_servers":  "10.244.1.5:29092","kafka_topic":    "my-topic", # This needs to be created manually
}# Since we are using self-signed certs we need to disable TLS verification
http_client = urllib3.PoolManager(cert_reqs='CERT_NONE')
urllib3.disable_warnings()# Initialize MinIO client
minio_client = Minio(config["minio_endpoint"],secure=True,access_key=config["minio_username"],secret_key=config["minio_password"],http_client = http_client)# Create destination bucket if it does not exist
if not minio_client.bucket_exists(config["dest_bucket"]):minio_client.make_bucket(config["dest_bucket"])print("Destination Bucket '%s' has been created" % (config["dest_bucket"]))# Initialize Kafka consumer
consumer = KafkaConsumer(bootstrap_servers=config["kafka_servers"],value_deserializer = lambda v: json.loads(v.decode('ascii'))
)consumer.subscribe(topics=config["kafka_topic"])try:print("Ctrl+C to stop Consumer\n")for message in consumer:message_from_topic = message.valuerequest_type = message_from_topic["EventName"]bucket_name, object_path = message_from_topic["Key"].split("/", 1)# Only process the request if a new object is created via PUTif request_type == "s3:ObjectCreated:Put":minio_client.fget_object(bucket_name, object_path, object_path)print("- Doing some pseudo image resizing or ML processing on %s" % object_path)minio_client.fput_object(config["dest_bucket"], object_path, object_path)print("- Uploaded processed object '%s' to Destination Bucket '%s'" % (object_path, config["dest_bucket"]))except KeyboardInterrupt:print("\nConsumer stopped.")
  • 我们将导入在此过程中之前安装的 pip 包
from minio import Minio
import urllib3from kafka import KafkaConsumer
import json
  • 我们不是每次都修改代码中的参数,而是在这个 config dict 中展示了一些常见的可配置参数。
config = {"dest_bucket":    "processed", # This will be auto created"minio_endpoint": "minio.tenant-lite.svc.cluster.local","minio_username": "minio","minio_password": "minio123","kafka_servers":  "10.244.1.5:29092","kafka_topic":    "my-topic", # This needs to be created manually
  • 我们启动的 MinIO 集群正在使用自签名证书。尝试连接时,我们需要确保它接受自签名证书。
http_client = urllib3.PoolManager(cert_reqs='CERT_NONE')
urllib3.disable_warnings()
  • 我们将检查用于存储已处理数据的目标存储桶是否存在;如果没有,那么我们将继续创建一个。
if not minio_client.bucket_exists(config["dest_bucket"]):minio_client.make_bucket(config["dest_bucket"])print("Destination Bucket '%s' has been created" % (config["dest_bucket"]))
  • 配置要连接的 Kafka 代理以及要订阅的主题
consumer = KafkaConsumer(bootstrap_servers=config["kafka_servers"],value_deserializer = lambda v: json.loads(v.decode('ascii'))
)consumer.subscribe(topics=config["kafka_topic"])
  • 当您停止使用者时,它通常会吐出堆栈跟踪,因为使用者应该永远运行使用消息。这将使我们能够干净地退出消费者
try:print("Ctrl+C to stop Consumer\n")… [truncated]except KeyboardInterrupt:print("\nConsumer stopped.")

如前所述,我们将持续等待,听取有关该主题的新消息。一旦我们得到一个主题,我们就会将其分解为三个部分

  • request_type:HTTP 请求的类型:GET、PUT、HEAD

  • bucket_name:添加新对象的存储桶的名称

  • object_path:存储桶中添加对象的对象的完整路径

for message in consumer:message_from_topic = message.valuerequest_type = message_from_topic["EventName"]bucket_name, object_path = message_from_topic["Key"].split("/", 1)
  • 每次您提出任何请求时,MinIO 都会向主题添加一条消息,该消息将由我们的 minio_consumer.py 脚本读取。因此,为了避免无限循环,我们只在添加新对象时进行处理,在本例中为请求类型 PUT。
if request_type == "s3:ObjectCreated:Put":minio_client.fget_object(bucket_name, object_path, object_path)
  • 您可以在此处添加客户代码来构建 ML 模型、调整图像大小和处理 ETL/ELT 作业。
print("- Doing some pseudo image resizing or ML processing on %s" % object_path)
  • 处理完对象后,它将被上传到我们之前配置的目标存储桶。如果存储桶不存在,我们的脚本将自动创建它。
minio_client.fput_object(config["dest_bucket"], object_path, object_path)print("- Uploaded processed object '%s' to Destination Bucket '%s'" % (object_path, config["dest_bucket"]))

你有它。除了一些样板代码之外,我们基本上在做两件事:

  • 侦听有关 Kafka 主题的消息

  • 将对象放入 MinIO 存储桶

该脚本并不完美 — 您需要添加一些额外的错误处理,但它非常简单。其余部分您可以使用自己的代码库进行修改。有关更多详细信息,请访问我们的 MinIO Python SDK 文档。

使用 MinIO 事件

我们已经构建了它,现在让我们看看它的实际效果。创建两个终端:

  • 终端 1 (T1):minio_consumer.py 运行的 Ubuntu Pod

  • 终端 2 (T2):带有 mc 的 Ubuntu Pod。

打开 T1 并运行我们之前使用 python3 编写的 minio_consumer.py 脚本。如果任何时候要退出脚本,可以键入 Ctrl+C

root@ubuntu:/# python3 minio_consumer.pyCtrl+C to stop Consumer

现在让我们打开 T2 并将一些对象 PUT 到我们之前使用 mc 创建的 MinIO 图像存储桶中。首先创建一个测试对象

root@ubuntu:/# touch rose.jpg
root@ubuntu:/# echo "a" > rose.jpg

将测试对象上传到 images 存储桶的几个不同路径

root@ubuntu:/# mc cp rose.jpg myminio/images --insecure/rose.jpg:            2 B / 2 B ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 55 B/s 0sroot@ubuntu:/# mc cp rose.jpg myminio/images/deeper/path/rose.jpg --insecure/rose.jpg:            2 B / 2 B ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 63 B/s 0s

在运行 MinIO 使用者脚本的另一个终端 T1 中,您应该会看到一些类似于下面的消息

root@ubuntu:/# python3 minio_consumer.py… [truncated]- Doing some pseudo image resizing or ML processing on rose.jpg- Uploaded processed object 'rose.jpg' to Destination Bucket 'processed'- Doing some pseudo image resizing or ML processing on deeper/path/rose.jpg- Uploaded processed object 'deeper/path/rose.jpg' to Destination Bucket 'processed'

我们还应该验证已处理的对象是否已上传到已处理的存储桶

root@ubuntu:/# mc ls myminio/processed[2022-08-12 01:03:46 UTC]     2B STANDARD rose.jpgroot@ubuntu:/# mc ls myminio/processed/deeper/path[2022-08-12 01:09:04 UTC]     2B STANDARD rose.jpg

如您所见,我们已成功将对象从未处理的原始数据上传到已处理的存储桶。

使用通知在 MinIO Enterprise Object Store 上构建工作流

我们在这里展示的只是您可以通过此工作流程实现的目标的一个示例。通过利用 Kafka 的持久消息传递和 MinIO Enterprise Object Store 的弹性存储,您可以构建复杂的 AI 应用程序,这些应用程序由可以扩展并跟上工作负载的基础设施提供支持,例如:

  • 机器学习模型

  • 图像大小调整

  • 处理 ETL / ELT 作业

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/58694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux: network: hw csum failure

文章目录 简介openvswitchifb: fix packets checksummellanoxiommu=ptmellanox 2mellanox 3建议简介 这里总结一下几个checksum的问题,仅供参考。需要看所使用的系统是否已经有了相应的fix。也可能是一个新问题,如果是新问题,恭喜发现了新的宝藏。 openvswitch Fix setti…

【Python】数据容器详解:列表、元组、字典与集合的推导式与公共方法

目录 &#x1f354; 列表集合字典的推导式 1.1 什么是推导式 1.2 为什么需要推导式 1.3 列表推导式 1.4 列表推导式 if条件判断 1.5 for循环嵌套列表推导式 1.6 字典推导式 1.7 集合推导式 &#x1f354; 数据序列中的公共方法 2.1 什么是公共方法 2.2 常见公共方法…

【PythonWeb开发】Flask-RESTful视图类基础知识

flask_restful 是一个扩展库&#xff0c;它为 Flask 提供了快速构建 RESTful API 的功能。使用 flask_restful 可以简化 RESTful API 的开发过程&#xff0c;减少样板代码&#xff0c;并且提供了一些高级特性&#xff0c;如 HTTP 方法的映射、资源路由的定义等。 在flask_restf…

1 C++ 编译属性 __attribute__((X))

__attribute__是GNU对标准C的扩展&#xff0c;可以用来设置函数属性&#xff08;Function Attribute&#xff09;、变量属性&#xff08;Variable Attribute&#xff09;和类型属性&#xff08;Type Attribute&#xff09;。 __attribute__使用 1 __attribute__((used))函数…

uniapp 使用uni.getRecorderManager录音,wav格式采样率低于44100,音频播放不了问题解决

如题&#xff1a;uniapp开发app端&#xff0c;使用uni.getRecorderManager录wav格式音频&#xff0c;采样率8000/16000都无法播放&#xff0c;44100可以播放。但由于项目需求需要录制采样率为8000的音频&#xff0c;于是引用了如下插件 插件地址(具体可以参考该插件的使用说明…

笔记:mysql升级 5.6至5.7

说明 一台已有数据的机器&#xff0c;停机升级&#xff0c;从MySQL Server5.6.48&#xff0c;升级到 5.7.38。 环境介绍 10.24.10.247&#xff0c;Mysql 5.6.48 CentOS Linux release 7.9.2009 (Core) 32G内存、500G数据盘/home&#xff1b; 实际数据量约120M&#xff0c;2个…

基于Unet卷积神经网络的脑肿瘤MRI分割

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【YOLO模型实现农作物病虫害虫识别带GUI界面】 2.【卫星图像道路检测DeepLabV3P…

uni-app在H5页面唤起小程序登录 然后再回到当前页面

在H5页面触发小程序方法跳转到登录页面 wx.miniProgram.navigateTo({ url: /pages/login/index?webviewRedirect encodeURIComponent(redirectUrl) }); 携带对应的返回地址 在等于成功之后触发webViewPage 携带token if (this.webviewRedirect) { const tempUrl decodeU…

Unity XR Interaction Toolkit 开发教程(1):OpenXR 与 XRI 概述【3.0 以上版本】

文章目录 &#x1f4d5;Unity XR 开发架构&#x1f50d;底层插件&#xff08;对接硬件&#xff09;&#x1f50d;高层 SDK&#xff08;面向应用交互层&#xff09; &#x1f4d5;OpenXR&#x1f4d5;XR Interaction Toolkit&#x1f50d;特点&#x1f50d;XRI 能够实现的交互类…

Diving into the STM32 HAL-----Interrupts

硬件管理就是处理异步事件。其中大部分来自硬件外围设备。例如&#xff0c;计时器达到配置的 period 值&#xff0c;或者 UART 在数据到达时发出警告。 中断是一个异步事件&#xff0c;它会导致按优先级停止执行当前代码&#xff08;中断越重要&#xff0c;其优先级越高;这将导…

Linux中SPI

参考资料 https://www.cnblogs.com/aaronLinux/p/6219146.html1.SPI 2.SPI传输 2.1传输示例 首先&#xff0c;CS0拉低选中的SPI Flash , 然后在每个时钟周期&#xff0c; DO输出对应的电平。 SPI FLASH会在每个时钟的上升沿读取D0的电平。2.2SPI模式 根据SCK的电平以及数据在…

自旋锁--死锁

本文内容整理自B站视频教程 自旋锁定义 内核发生访问资源冲突的时候&#xff0c;可以有两种锁的解决方案选择&#xff1a;一个是原地等待&#xff0c;一个是挂起当前进程&#xff0c;调度其他进程执行(休眠)。 spinlock是内核中提供的一种比较常见的锁机制&#xff0c;自旋锁…

ICM20948 DMP代码详解(107)

接前一篇文章:ICM20948 DMP代码详解(106) 上一回开始解析inv_set_hw_smplrt_dmp_odrs函数中的以下代码片段: if (s->b2s_status != 0) {unsigned short lB2SMinDly = min(INV_ODR_DEFAULT_B2S, minDly_accel);lB2SMinDly = 1000/(get_multiple_56_rate(lB2SMinDly));dmp…

【C++】继承和多态常见的面试问题

文章目录 继承笔试面试题1. 什么是菱形继承&#xff1f;菱形继承的问题是什么&#xff1f;2. 什么是菱形虚拟继承&#xff1f;如何解决数据冗余和二义性&#xff1f;3. 继承和组合的区别&#xff1f;什么时候用继承&#xff1f;什么时候用组合&#xff1f; 选择题 多态概念考察…

Android gradle和maven国内镜像地址

在Android 开发中经常会出现gradle或者maven依赖下载过慢或者失败的情况&#xff0c;如果出现这种情况的话&#xff0c;那就需要使用国内镜像地址&#xff0c;本文章仅作记录&#xff0c;方便后续查取。 gradle国内镜像地址 这里提供的是腾讯的国内gradle镜像地址。 https://…

人工智能:机遇与挑战

人工智能&#xff08;AI&#xff09;作为当今世界科技发展的前沿领域&#xff0c;正在以前所未有的速度和规模影响着我们的生活和工作方式。AI技术的应用前景广阔&#xff0c;从医疗健康到金融服务&#xff0c;从教育到交通&#xff0c;再到娱乐和家庭生活&#xff0c;AI正在逐…

数字IC开发:布局布线

数字IC开发&#xff1a;布局布线 前端经过DFT&#xff0c;综合后输出网表文件给后端&#xff0c;由后端通过布局布线&#xff0c;将网表转换为GDSII文件&#xff1b;网表文件只包含单元器件及其连接等信息&#xff0c;GDS文件则包含其物理位置&#xff0c;具体的走线&#xff1…

Python爬虫的“京东大冒险”:揭秘商品类目信息

开篇&#xff1a;欢迎来到Python的奇幻森林 在这个数据驱动的时代&#xff0c;我们就像一群探险家&#xff0c;穿梭在数字的森林中&#xff0c;寻找着隐藏的宝藏——商品类目信息。今天&#xff0c;我们将带领你一起&#xff0c;用Python这把锋利的剑&#xff0c;深入京东的神…

Flutter 13 网络层框架架构设计,支持dio等框架。

在移动APP开发过程中&#xff0c;进行数据交互时&#xff0c;大多数情况下必须通过网络请求来实现。客户端与服务端常用的数据交互是通过HTTP请求完成。面对繁琐业务网络层&#xff0c;我们该如何通过网络层架构设计来有效解决这些问题&#xff0c;这便是网络层框架架构设计的初…

LLM大模型部署实战指南:部署简化流程

LLM大模型部署实战指南:Ollama简化流程,OpenLLM灵活部署,LocalAI本地优化,Dify赋能应用开发 1. Ollama 部署的本地模型(🔺) Ollama 是一个开源框架,专为在本地机器上便捷部署和运行大型语言模型(LLM)而设计。,这是 Ollama 的官网地址:https://ollama.com/ 以下是其…