如何使用io_uring构建快速响应的I/O密集型应用?

本文分享自华为云社区《如何使用io_uring构建快速响应的I/O密集型应用》,作者: Lion Long 。

当涉及构建快速响应的I/O密集型应用时,io_uring技术展现出了其卓越的潜力。本文摘要将深入探讨如何充分利用io_uring的特性来优化应用程序性能。通过异步I/O操作和高效事件处理,io_uring为开发人员提供了一种强大工具,能够显著减少I/O等待时间并实现更高的吞吐量。

一、同步与异步

用于形容两者的关系,是同时存在的参考物。

同步: 所谓同步,就是发起一个请求时,在返回结果前,该调用不会返回。类似串行的概念。

异步: 异步的概念和同步相对,当发起一个请求时,该调用立刻返回,不等待结果,实际返回的结果由另外的线程 / 进程处理。类似并行的概念。

cke_114.png

二、io_uring系统调用

io_uring从linix 5.1内核开始支持,但是到linix5.10后才达到比较好的支持,所以使用io_uring编程时,最好使用linix 5.10版本之后。升级linux内核可以参考ubuntu升级Linux内核版本_ubuntu 升级内核_Lion Long的博客-优快云博客。

内核提供三个接口,函数原型:

#include <linux/io_uring.h>

int io_uring_setup(u32 entries,struct io_uring_params *p);

int io_uring_register(unsigned int fd,unsigned int opcode,void *arg,unsigned int nr_args);

int io_uring_entry(unsigned int fd,unsigned int to_submit,

unsigned int min_complete,unsigned int flags,sigset_t *sig);

2.1、io_uring_setup

函数原型:

#include <linux/io_uring.h>

int io_uring_setup(u32 entries,struct io_uring_params *params);

系统调用,设置提交队列(SQ)和完成队列(CQ),其中至少包含entries条目,并返回一个文件描述符,可用于对io_urine实例执行后续操作。SQ和CQ在用户空间和内核之间共享,这减少了在启动和完成I/O时复制数据的消耗。

参数

含义

entries

队列元素个数

params

配置io_uring,向内核传递选项,内核使用params传递有关环形缓冲区的信息。

成功时返回新的文件描述符。然后,应用程序可以在随后的mmap系统调用中提供文件描述符,以映射提交队列(submission queues)和完成队列(completion queues),或者传给io_uring_register() / io_uring_enter()系统调用。

出现错误时,返回负错误代码。调用方不应依赖errno变量。

错误码

含义

EFAULT

参数超出了您的可访问地址空间。

EINVAL

resv数组包含非零数据,p.flags包含非零支持标志,条目超出界限。

EMFILE

已达到每个进程打开文件描述符数量的限制。

ENFILE

已达到系统范围内打开文件总数的限制。

ENOMEM

可用的内核资源不足。

EPERM

已指定IORING_SETUP_SQPOLL,但调用方的有效用户ID没有足够的权限。

2.2、io_uring_register

函数原型:

#include <linux/io_uring.h>

int io_uring_register(unsigned int fd,unsigned int opcode,void *arg,unsigned int nr_args);

注册用于异步 I/O 的文件或用户缓冲区,使内核能长时间持有对该文件在内核内部的数据结构引用, 或创建应用内存的长期映射, 这个操作只会在注册时执行一次,而不是每个 I/O 请求都会处理,因此大大减少了每个IO的开销。

参数

含义

fd

文件描述符 ,是io_uring_setup返回的fd

opcode

操作代码

成功时返回0。

出现错误时,返回负错误代码。调用方不应依赖errno变量。

2.3、io_uring_enter

#include <linux/io_uring.h>

int io_uring_enter(unsigned int fd,unsigned int to_submit,

unsigned int min_complete,unsigned int flags,sigset_t *sig);

这个系统调用使用共享的 SQ 和 CQ初始化和完成(initiate and complete)I/O。

单次调用同时执行:提交新的 I/O 请求;等待 I/O 完成。

参数:

  • fd:io_uring_setup返回的文件描述符。
  • to_submit:指定要从提交队列提交的I/O数。

成功返回使用的I/O数量。如果to_submit为零或提交队列为空,则该值可以为零。注意,如果创建环时指定了IORING_SETUP_SQPOLL,则返回值通常与to_submit相同,因为提交发生在系统调用的上下文之外。

与提交队列条目相关的错误将通过完成队列条目返回,而不是通过系统调用本身返回。

不代表提交队列条目发生的错误将通过系统调用直接返回。在出现这种错误时,返回负错误代码。调用方不应依赖errno变量。

更多信息可以执行 man io_uring_enter查看

2.4、执行流程

cke_115.png

三、io_uring相关结构体

3.1、struct io_uring_params 结构体

struct io_uring_params {

__u32 sq_entries;

__u32 cq_entries;

__u32 flags;

__u32 sq_thread_cpu;

__u32 sq_thread_idle;

__u32 features;

__u32 wq_fd;

__u32 resv[3];

struct io_sqring_offsets sq_off;

struct io_cqring_offsets cq_off;

};

flags、sq_thread_cpu和sq_ thread_idle字段用于配置io_uring实例。flags是一个位掩码,其中0个或多个以下值一起或:

标志

含义

IORING_SETUP_IOPOLL

执行繁忙等待I/O完成,而不是获取通过异步IRQ(中断请求)发送通知。

IORING_SETUP_SQPOLL

创建一个内核线程来执行提交队列轮询

IORING_SETUP_SQ_AFF

轮询线程将绑定到结构io_uring_params的sq_thread_cpu字段中设置的cpu。

IORING_SETUP_CQSIZE

使用struct io_uring_params创建完成队列

IORING_SETUP_CLAMP

如果指定了此标志,并且如果条目超过IORING_MAX_ENTERIES,则条目将被钳制在IORING_MAX_ENTERIES。如果设置了标志IORING _SETUP_SQPOLL,并且如果struct io_uring_params的值cq_entries超过IORING_MAX_ENTERIES,则它将被箝位在IORING_MAX_ENTERIES。

IORING_SETUP_ATTACH_WQ

此标志应与struct io_uring_params一起设置

IORING_SETUP_R_DISABLED

如果指定了该标志,io_uring环将以禁用状态启动。

3.2、struct io_cqring_offsets 结构体

struct io_cqring_offsets {

__u32 head;

__u32 tail;

__u32 ring_mask;

__u32 ring_entries;

__u32 overflow;

__u32 cqes;

__u32 flags;

__u32 resv[3];

};

3.3、struct io_uring_sqe 结构体

struct io_uring_sqe {

__u8 opcode; /* type of operation for this sqe */

__u8 flags; /* IOSQE_ flags */

__u16 ioprio; /* ioprio for the request */

__s32 fd; /* file descriptor to do IO on */

union {

__u64 off; /* offset into file */

__u64 addr2;

};

union {

__u64 addr; /* pointer to buffer or iovecs */

__u64 splice_off_in;

}

__u32 len; /* buffer size or number of iovecs */

union {

__kernel_rwf_t rw_flags;

__u32 fsync_flags;

__u16 poll_events; /* compatibility */

__u32 poll32_events; /* word-reversed for BE */

__u32 sync_range_flags;

__u32 msg_flags;

__u32 timeout_flags;

__u32 accept_flags;

__u32 cancel_flags;

__u32 open_flags;

__u32 statx_flags;

__u32 fadvise_advice;

__u32 splice_flags;

__u32 rename_flags;

__u32 unlink_flags;

__u32 hardlink_flags;

};

__u64 user_data; /* data to be passed back at completion time */

union {

struct {

/* index into fixed buffers, if used */

union {

/* index into fixed buffers, if used */

__u16 buf_index;

/* for grouped buffer selection */

__u16 buf_group;

}

/* personality to use, if used */

__u16 personality;

union {

__s32 splice_fd_in;

__u32 file_index;

};

};

__u64 __pad2[3];

};

};

3.4、struct io_uring_cqe 结构体

struct io_uring_cqe {

__u64 user_data; /* sqe->data submission passed back */

__s32 res; /* result code for this event */

__u32 flags;

};

四、liburing库安装

(1)下载源码。

git clone https://github.com/axboe/liburing.git

(2)进入liburing。

cd liburing

(3)配置。

./configure

(4)编译和安装。

make && sudo make install

(5)编译应用程序,一定要指定库 -luring -D_GUN_SOURCE。

gcc -o io_uring_test io_uring_test.c -luring -D_GUN_SOURCE

五、liburing提供的接口

5.1、io_uring_queue_init_params

函数原型:

#include <liburing.h>

int io_uring_queue_init(unsigned entries,

struct io_uring *ring,

unsigned flags);

int io_uring_queue_init_params(unsigned entries,

struct io_uring *ring,

struct io_uring_params *params);

io_uring_queue_init()函数执行io_uring_setup()系统调用来初始化内核中的提交队列和完成队列,其中至少包含提交队列中的条目,然后将生成的文件描述符映射到应用程序和内核之间共享的内存中。

默认情况下,CQ环的条目数将是SQ环条目指定的条目数的两倍。这对于常规文件或存储工作负载足够,但对于网络工作负载可能太小。SQ环条目并没有限制环可以支持的进程中请求的数量,它只是限制了一次(批)提交给内核的数量。如果CQ环溢出,例如,在应用程序可以获取它们之前,生成的条目比环中的条目多,则环进入CQ环溢流状态。这通过在SQ环标志中设置IORING_SQ_CQ_OVERFLOW来指示。除非内核耗尽可用内存,否则不会删除条目,但这是一条慢得多的完成路径,会减慢请求处理速度。因此,应该避免这种情况,并且CQ环的大小适合于工作负载。在struct io_uring_params中设置cq_entries将告诉内核为cq环分配这么多条目,与给定条目中的SQ环大小无关。如果该值不是2的幂,则将四舍五入到最接近的2的幂。

成功时,io_uring_queue_init返回0,ring将指向包含io_RUING队列的共享内存。失败时返回-errno。flags将传递给io_uring_setup系统调用。

如果使用io_uring_queue_init_params(),则params指示的参数将直接传递到io_uring_setup系统调用。成功后返回0,应通过对io_uring_queue_exit的相应调用释放ring持有的资源。失败时返回-errno。

5.2、io_uring_get_sqe

函数原型:

#include <liburing.h>

struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring);
  • 从属于ring参数的提交队列中获取下一个可用的提交队列条目。
  • 成功时返回一个指向提交队列条目的指针。
  • 失败时返回NULL。

如果返回了提交队列条目,则应通过io_uring_prep_read()等准备函数之一填写该条目,并通过io_ uring_submit()提交。

如果返回NULL,则SQ环当前已满,必须提交条目进行处理,然后才能分配新条目。

5.3、io_uring_prep_accept

函数原型:

#include <sys/socket.h>

#include <liburing.h>

void io_uring_prep_accept(struct io_uring_sqe *sqe,

int sockfd,

struct sockaddr *addr,

socklen_t *addrlen,

int flags);

void io_uring_prep_accept_direct(struct io_uring_sqe *sqe,

int sockfd,

struct sockaddr *addr,

socklen_t *addrlen,

int flags,

unsigned int file_index);

void io_uring_prep_multishot_accept(struct io_uring_sqe *sqe,

int sockfd,

struct sockaddr *addr,

socklen_t *addrlen,

int flags);

void io_uring_prep_multishot_accept_direct(struct io_uring_sqe *sqe,

int sockfd,

struct sockaddr *addr,

socklen_t *addrlen,

int flags);

这些函数准备一个异步accept()请求。

io_uring_prep_accept()函数准备接受请求。提交队列条目sqe被设置为使用文件描述符sockfd开始接受由addr处的套接字地址和结构长度addrlen描述的连接请求,并在标志中使用修饰符标志。

注意:io_uring_prep_accept()与在结构中传递数据的任何请求一样,在成功提交请求之前,该数据必须保持有效。它不需要在完成之前保持有效。一旦请求被提交,内核状态就稳定了。

5.4、io_uring_prep_recv

函数原型:

#include <liburing.h>

void io_uring_prep_recv(struct io_uring_sqe *sqe,

int sockfd,

void *buf,

size_t len,

int flags);

void io_uring_prep_recv_multishot(struct io_uring_sqe *sqe,

int sockfd,

void *buf,

size_t len,

int flags);

描述:

io_uring_prep_recv()函数准备recv请求。提交队列条目sqe被设置为使用文件描述符sockfd来开始将数据接收到大小为size且具有修改标志flags的缓冲区目的地buf中。

此函数用于准备异步recv()请求。

multishot版本允许应用程序发出单个接收请求,当数据可用时,该请求会重复发布CQI。

5.5、io_uring_prep_send

函数原型:

#include <liburing.h>

void io_uring_prep_send(struct io_uring_sqe *sqe,

int sockfd,

const void *buf,

size_t len,

int flags);

描述:

io_uring_prep_send()函数准备发送请求。提交队列条目sqe被设置为使用文件描述符sockfd开始从buf发送大小为size的数据,并带有修改标志flags。

此函数用于准备异步send()请求。

5.6、io_uring_submit (重要)

函数原型:

#include <liburing.h>

int io_uring_submit(struct io_uring *ring);

描述:

  • 将下一个事件提交到属于ring的提交队列。
  • 调用者使用io_uring_get_sqe()检索提交队列条目(SQE)并使用提供的帮助程序之一准备SQE后,可以使用io_ uring_ submit()提交。

返回值:

  • 成功时返回提交的提交队列条目数。
  • 失败时返回-errno。

5.7、io_uring_submit_and_wait (重要)

函数原型:

#include <liburing.h>

int io_uring_submit_and_wait(struct io_uring *ring,unsigned wait_nr);

描述:

  • 将下一个事件提交到属于环的提交队列,并等待wait_nr完成事件。
  • 在调用方使用io_uring_get_sqe()检索提交队列条目(SQE)并准备SQE之后,可以使用io_ uring_ submit_and_wait()提交它。

返回值:

  • 成功时返回提交的提交队列条目数。
  • 失败时返回-errno。

5.8、io_uring_wait_cqe

函数原型:

#include <liburing.h>

int io_uring_wait_cqe(struct io_uring *ring,

struct io_uring_cqe **cqe_ptr);

描述:

  • 等待来自属于环参数的队列的io完成,必要时等待。如果调用时环中已有事件可用,则不会发生等待。成功时填写cqe_ptr参数。
  • 在呼叫者提交了具有io_uring_submit()的请求之后,应用程序可以使用io_uring_wait_cqe检索完成。

返回值:

  • 成功时返回0,并填写cqe_ptr参数。失败时返回-errno。返回值指示等待CQE的结果,并且与CQE结果本身无关。

5.9、io_uring_peek_batch_cqe

#include <liburing.h>

int io_uring_peek_cqe(struct io_uring *ring,

struct io_uring_cqe **cqe_ptr);



int io_uring_peek_batch_cqe(struct io_uring *ring,

struct io_uring_cqe **cqe_ptr,

int count);

描述:

  • io_uring_peek_cqe()函数从属于ring参数的队列返回IO完成(如果有)。成功返回后,cqe_ptr参数将填充有效的cqe条目。
  • 此函数不进入内核等待事件,只有在CQ环中已经可用时才返回事件。
  • io_uring_peek_batch_cqe是对io_uring_peek_cqe的封装,表示一次最多从ring参数获取count个IO完成。

返回值:

  • 成功时io_uring_peek_cqe()返回0,并填写cqe_ptr参数。
  • 失败时返回-EAGAIN。
  • 成功时io_uring_peek_cqe()返回IO完成数量,并填写cqe_ptr参数。
  • 失败时返回-EAGAIN。

5.10、io_uring_cq_advance

#include <liburing.h>

void io_uring_cq_advance(struct io_uring *ring,

unsigned nr);

描述:

io_uring_cq_advance()函数将属于ring参数的nr个io完成标记为消耗。

在呼叫者已经使用io_uring_submit()提交请求之后,应用程序可以使用io_ uring_ wait_cqe()、io_uring_peek_cqe()或任何其他cqe检索帮助器检索完成,并使用io_uring_cqe_seen()将其标记为。

函数io_uring_cqe_seen()调用io_ uring_cq_advance()函数。

完成必须标记为可见,以便可以重用它们的插槽。否则将导致在下一次调用时返回相同的完成。

5.11、更多接口

除了bind没有异步接口,其他基本都有。比如io_uring_prep_connect()、io_uring_prep_close()等等。

六、基于liburing的TCP服务器实现

在应用层使用io_uring,主要使用liburing库,它提供丰富的用户接口,底层调用的是三个内核io_uring系统调用。

基于liburing的TCP服务器实现示例代码:

#include <stdio.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <liburing.h>

#define ENTRIES_LENGTH 4096

#define RING_CQE_NUMBER 10

#define BUFFER_SIZE 1024

struct conninfo

{

int connfd;

int type;

};

enum

{

READ,

WRITE,

ACCPT,

};

void set_accept_event(struct io_uring *ring,int fd,

struct sockaddr* clientaddr, socklen_t *len,unsigned flags)

{

struct io_uring_sqe *sqe = io_uring_get_sqe(ring);//·µ»Ø¶ÓÁÐÊ×µØÖ·

io_uring_prep_accept(sqe, fd, clientaddr, len, flags);

struct conninfo ci = {

.connfd = fd,

.type = ACCPT

};

memcpy(&sqe->user_data, &ci, sizeof(struct conninfo));

}

void set_read_event(struct io_uring *ring, int fd, void *buf, size_t len, int flags)

{

struct io_uring_sqe *sqe = io_uring_get_sqe(ring);//·µ»Ø¶ÓÁÐÊ×µØÖ·

io_uring_prep_recv(sqe, fd, buf, len, flags);

struct conninfo ci = {

.connfd = fd,

.type = READ

};

memcpy(&sqe->user_data, &ci, sizeof(struct conninfo));

}

void set_write_event(struct io_uring *ring, int fd, void *buf, size_t len, int flags)

{

struct io_uring_sqe *sqe = io_uring_get_sqe(ring);//·µ»Ø¶ÓÁÐÊ×µØÖ·

io_uring_prep_send(sqe, fd, buf, len, flags);

struct conninfo ci = {

.connfd = fd,

.type = WRITE

};

memcpy(&sqe->user_data, &ci, sizeof(struct conninfo));

}

int main()

{

int listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd == -1)

return -1;

struct sockaddr_in serveraddr,clientaddr;

serveraddr.sin_family = AF_INET;

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

serveraddr.sin_port = htons(9999);

if (-1 == bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)))

return -2;

listen(listenfd, 10);

struct io_uring_params params;

memset(&params,0,sizeof(params));

struct io_uring ring;

io_uring_queue_init_params(ENTRIES_LENGTH,&ring,&params);

socklen_t clientlen = sizeof(clientaddr);



set_accept_event(&ring, listenfd, (struct sockaddr*)&clientaddr,&clientlen, 0);

char buffer[BUFFER_SIZE] = { 0 };

while (1)

{

struct io_uring_cqe *cqe;

io_uring_submit(&ring);

int ret = io_uring_wait_cqe(&ring,&cqe);

struct io_uring_cqe *cqes[RING_CQE_NUMBER];

int cqecount=io_uring_peek_batch_cqe(&ring, cqes, RING_CQE_NUMBER);

int i = 0;

unsigned count =0;

for (i = 0; i < cqecount; i++)

{

count++;

cqe = cqes[i];

struct conninfo ci;

memcpy(&ci, &cqe->user_data, sizeof(struct conninfo));

if (ci.type == ACCPT)

{

int connfd = cqe->res;



set_read_event(&ring, connfd, buffer, BUFFER_SIZE, 0);



set_accept_event(&ring, listenfd, (struct sockaddr*)&clientaddr,&clientlen, 0);

}

else if (ci.type == READ)

{

int bufsize = cqe->res;

if(bufsize==0)

{

close(ci.connfd);

}

else if(bufsize<0)

{



}

else{

//set_read_event(&ring, ci.connfd, buffer, 1024, 0);

printf("buff: %s\n",buffer);

set_write_event(&ring, ci.connfd, buffer, bufsize, 0);

}

}

else if(ci.type == WRITE)

{

set_read_event(&ring, ci.connfd, buffer, BUFFER_SIZE, 0);

}



}

io_uring_cq_advance(&ring,count);

}

return 0;

}

总结

  1. io_uring主要由三部分构成:内核提供的三个系统调用接口(io_uring_setup、io_uring_register、io_uring_enter),内核实现的系统调用,应用层提供的liburing库。
  2. io_uring_submite会在底层协议栈执行accept、recv、send等功能。从fio测试磁盘IO的测试结果来看,io_uring的IOPS与libaio相同,是psync的两倍。
  3. io_uring的异步操作在内核下完成,用户态调用api是感觉不到异步操作的。
  4. io_uring实现TCP服务器的函数调用框图:

cke_116.png

号外!

cke_112284.jpeg

华为将于2023年9月20-22日,在上海世博展览馆和上海世博中心举办第八届华为全联接大会(HUAWEICONNECT 2023)。本次大会以“加速行业智能化”为主题,邀请思想领袖、商业精英、技术专家、合作伙伴、开发者等业界同仁,从商业、产业、生态等方面探讨如何加速行业智能化。

我们诚邀您莅临现场,分享智能化的机遇和挑战,共商智能化的关键举措,体验智能化技术的创新和应用。您可以:

  • 在100+场主题演讲、峰会、论坛中,碰撞加速行业智能化的观点
  • 参观17000平米展区,近距离感受智能化技术在行业中的创新和应用
  • 与技术专家面对面交流,了解最新的解决方案、开发工具并动手实践
  • 与客户和伙伴共寻商机

感谢您一如既往的支持和信赖,我们热忱期待与您在上海见面。

大会官网:华为全联接大会 2023 | HUAWEI CONNECT 2023

欢迎关注“华为云开发者联盟”公众号,获取大会议程、精彩活动和前沿干货。

点击关注,第一时间了解华为云新鲜技术~

相关推荐

鸿蒙案例上新啦 | 购物、听歌、健身:15个模板带你一键激活社交娱乐

页面层级如何组织、跨页共享状态如何同步、列表与详情及个人中心如何形成稳定闭环。鸿蒙开发实践中心将这些高频消费与互动场景沉淀为可参考的标准模板,提供从业务架构到界面实现的快捷实践入口。更多实战案例欢迎前往鸿蒙开发实践中心案例中心查看并开启云端体验。

华为云官方博客 354

鸿蒙案例上新啦 | 出门打车、到家上课:25个模板带你一屏打通日常生活

如何合理拆分页面组件、如何建立单一可信的状态源、如何让用户在每一步操作中都获得明确反馈。鸿蒙开发实践中心以标准化的应用与元服务模板为入口,将清晰的业务架构与可复用的代码结构直观呈现。不妨立即挑选一个感兴趣的方向进入云端环境,从页面布局、组件封装、状态管理到路由组织,亲手跑通你的鸿蒙实战项目。

华为云官方博客 335

LakeAgent:DWS数据仓库的第二大脑,告别 “翻译式运维”,迈入智能自治时代

和普通 SQL 改写工具不同,LakeAgent 自动做多方案代价对比,主动规避负优化陷阱:补充分区键过滤实现剪枝,扫描分区由 37 收敛至 1,执行代价从 758.28 降至 113.74;未来的数据仓库,将不止能算、能存,更能看懂自己、诊断自己、理解自己。长久以来,数仓的智能都依附于人:信号需要人解读,瓶颈需要人研判,经验困在个体里,无法随底座永续生长。CPU 高、CPU 告警、CPU 诊断、CPU 使用率过高、CPU 满。语法、错误码、计费、性能调优、最佳实践、故障处置等全场景内容。

华为云官方博客 563

如何使用RDS Supabase后端BaaS能力:文件存储(File Storage)

• product-images(公开桶,允许公共读取):策略名称"Public read for product-images",允许SELECT,目标角色anon,策略定义bucket_id = 'product-images'。上传/删除需另配INSERT/DELETE策略,详见SQL。• product-specs(私有桶,仅认证用户访问自己的文件夹):建议拆为上传、读取、删除三条策略,策略定义均为 bucket_id = 'product-specs' 且仅限本人文件夹(详见下文 SQL)。

华为云官方博客 483

如何使用RDS Supabase后端BaaS能力:实时订阅与推送(Realtime)

Realtime 把数据库的每次变更同步到客户端:表里增、删、改一行,订阅者无需刷新页面或主动请求即可秒级收到。三大能力各司其职:• Postgres Changes — 监听表的 INSERT/UPDATE/DELETE,变化即通知• Broadcast — 客户端之间直接互发,适合瞬时通知、协同编辑• Presence — 跟踪频道里“谁在线”典型场景有实时数据展示(订单、库存、监控指标即时刷新)、即时通讯(消息收发、在线名单、“对方正在输入”)、协同编辑与实时通知。

华为云官方博客 473

AI Agent如何通过MCP连接到华为云RDS Supabase应用平台

Schema元数据列出所有可访问的表(按schema分组)。Schema元数据列出表的列及元数据(类型/默认值/约束)。Schema元数据列出所有约束(PK/FK/UNIQUE/CHECK/EXCLUDE)。可按schema/表/类型过滤。Schema元数据列出所有外键关系。可按schema/表过滤。Schema元数据列出所有索引及定义和大小。可按schema/表过滤。Schema元数据列出已应用的数据库迁移记录。Schema元数据列出已安装的PostgreSQL扩展。

华为云官方博客 480

华为大数据Flink让每一 CU 算力,跑出开源 5.74 倍的性能

1. 开源Apache Flink 已成为业界流计算事实标准,但在极端重负载场景下存在性能瓶颈。2. 华为大数据Flink通过多项自研深度优化,在执行计划、算子执行、状态存储三个层面构建协同的优化体系。3. Nexmark Benchmark 测试结果:整体性能提升 5.74 倍,极端重负载场景性能领先最高 18.3 倍。4. 100% 兼容 Apache Flink 1.20,业务代码零改造,无缝迁移。

华为云官方博客 384

LakeAgent实战 | 业务分析篇从一句提问到业务分析

本文以“订单金额变化”分析为例,展示LakeAgent如何通过自然语言提问,结合DataArtsStudio的数据资产与专业技能,帮助业务人员快速定位数据、生成SQL、追踪血缘、生成报告。从问题出发,逐步实现数据发现、变化洞察、原因追溯与团队协作,最终形成可复用的分析流程与企业规则,显著提升数据分析效率与一致性。

华为云官方博客 394

华为云RDS Supabase AI应用已开放公测 :30分钟搭建AI应用后端

认证、存储、实时推送、数据库API——4个后端模块,传统开发需要数周。今天,你只需要30分钟。AI创业公司的全栈开发工程师。上周老板说"下周要上线的AI对话应用,后端你来搞"——认证鉴权、数据库接口、文件存储、实时推送,每一个模块都需要数周搭建,而市场不会等你。小张打开华为云RDS Supabase,30分钟搭好认证、数据库API、对象存储,剩下的时间全用来打磨AI交互体验。基于开源Supabase+华为云RDS PostgreSQL全托管能力,为开发者提供。

华为云官方博客 402

如何使用RDS Supabase后端BaaS能力:数据库函数(Database Function)

上一篇介绍了 Database Data API——建表即自动生成增删改查接口,解决单表读写,但聚合统计、跨表事务、字段自动维护等逻辑已超出其能力边界。本篇推进到数据库函数(Database Function):把业务逻辑封装进数据库,前端通过 .rpc() 调用,由触发器自动响应数据变更。上一篇中,小张基于 Data API 完成了产品目录的建表与基础读写。但新需求随之而来:按分类统计产品数与价格区间、上架新品同时写产品表与定价表、产品修改后自动刷新更新时间。

华为云官方博客 467

如何使用RDS Supabase后端BaaS能力:创表即生成API(Database Data API)

认证、存储、实时推送、数据库API——4个后端模块,传统开发要数周。本系列逐个拆解,首篇聚焦数据库API(Database Data API):建表即得 API,无需手写后端。小张,AI创业公司的全栈工程师。老板让他做个产品目录页,展示产品与价格、支持上下架。传统做法要搭后端、写接口、配权限,工期少说1-2周;而在华为云RDS Supabase,建两张表、应用 SDK 直连,几分钟增删改查全跑通。

华为云官方博客 483

从一句话到一个能出去的链接,AI开发者空间做了什么

自行搭建的 Agent、正在使用的开源项目、团队既有的工具,都可以接入,可以通过AI创建或者手动搭建环境;华为云 AI开发者空间——面向开发者的云端一站式开发平台,做的就是把这段路接上:环境免安装,浏览器打开即为完整的 Linux 运行环境,预置的 AI 智能体开箱即用。第一个任务建议选能出结果的:做一个游戏、生成一个页面、创建一台实例,从需求走到可访问的链接,一次就能看清这个环境在做什么。沙箱是一个完整的 Linux 环境,依赖、服务、端口都是真实的,不是模拟。环境释放后,权限随之失效。

华为云官方博客 430

华为云码道配置自定义大模型,四种方式完整实操

案例介绍。

华为云官方博客 633

图数据库:实现穿透式监管的数据基座

穿透式监管标志着国企监管从“管企业”向“管资本”转型过程中的关键一跃。而图数据库正是这一跃的技术支点。从股权穿透到资金链穿透,从供应链穿透到数据穿透,华为GES图数据库正在将“穿透式监管”从理念变为可落地、可操作的实践。无论是天眼查式的全量链路查询,还是某集团财经的税务规则判断,抑或是芯片供应链式的部件风险分析,乃至通过Palantir构建决策知识图谱,其底层逻辑都是一致的——用图的力量,穿透一切形式的“隔离层”,直抵风险本质与责任核心。

华为云官方博客 668

《公共云三十问》正式收官,奔赴企业AI百场景新征程

今年6月底,公共云产业联盟重点推出《公共云三十问》专栏,以每周三问的节奏,连载十周,解读《先进公共云》白皮书,分享国计民生系列案例,旨在凝聚共识、推动落地实践。同时,专栏分析公共云在产业升级、民生福祉、科技创新、全球发展等方面的作用,梳理中国特色公共云发展路径:以普惠云拓展用云广度,以智算云提升用云深度,以自主云夯实用云厚度,以全球云打开用云跨度。这十问从专属云、行业云切入,深入政务、金融、交通、电力、钢铁、化工、油气、制造等国计民生场景,回答公共云“怎么用”。

华为云官方博客 474

开发者小技巧|IAM配置,让码道代码智能体连续30天免登录

案例介绍。

华为云官方博客 648

码道深度对接CodeArts,让需求自动落地为代码

案例介绍。

华为云官方博客 722

【公共云三十问 之三十】拥抱AI,企业如何建设面向智能体的专属云?

企业可分阶段建设覆盖开发、运行、运营及安全的一体化智能体平台——从构建一站式、高低码协同的智能体开发平台,到打造高性能、极致弹性的运行时环境,再到搭建AgentOps驱动的持续运营与运维体系,同时构建端到端、多层次的全链路安全防护体系。在数据湖建设方面,遵循“存量复用、平滑演进、AI导向、分步迭代”原则,分三阶段推进——打造AI多模数据湖核心能力、完成存算分离与统一元数据管理、实现闭环赋能全面支撑智能体规模化落地,在保护既有投资的前提下将传统数据平台转型为AI数据专属供给平台。

华为云官方博客 824

【公共云三十问 之二十九】国计民生之制造:制造云如何重塑数智时代的新质生产力?

平台打通软件交付的完整路径,覆盖需求管理、代码托管、代码检查、编译构建、制品仓库、部署、测试等关键环节,支持大模型能力融入研发全流程,实现从需求到交付的端到端管理。通过构建“研发一朵云”,方案打破地域与组织壁垒,实现跨团队协同开发,有效缩短软件交付周期,助力工业制造企业从“传统研发”走向“敏捷研发”,加速数智化转型进程。当制造云真正成为数据流通的平台、AI创新的底座,公共云的社会价值将从基础设施层向生产场景层持续延伸,为新型工业化建设和制造强国战略注入源源不断的动力,重塑数智时代的中国制造新质生产力。

华为云官方博客 791

告别重复手工迁仓,码道MCP+Skill实现仓库批量迁移

案例介绍。

华为云官方博客 791

【公共云三十问 之二十八】国计民生之油气:智算云如何叩响数智时代的“地心蓝金”?

西南油气田以“向地球深部要资源”为战略方向,联合以华为云Stack为代表的公共云服务商共同打造统一算力底座,建设西南区域数据湖与通用技术平台,构建“勘探开发工程技术、天然气生产过程管控、天然气产运储销”等三个一体化协同应用场景,支撑油气勘探、开发生产、管输储运等全业务链的数智化转型。当智算云真正成为数据流通的平台、AI创新的底座,油气田得以将算力效能、数据价值与智能技术深度融入勘探开发全链条,将“看不见的算力”转化为“摸得着的储量”,以智能化手段持续降低勘探风险、缩短发现周期、提高采收效率,确保生产安全。

华为云官方博客 613

【公共云三十问 之二十七】国计民生之化工:数智云如何重塑传统化工新范式?

在架构方面,方案构建云边协同的统一体系,涵盖AI协同、数据协同与运营协同三大维度——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现“边用边学”的智能闭环,模型平均精度提升20%以上。此外,方案提供一站式企业级工业物联网平台、数据湖与数据治理平台,覆盖工业数据分析“采、存、算、管、用”全流程,打通生产现场与管理系统间的数据壁垒,有效消除数据孤岛。层面,方案充分发挥软硬协同优势,实现计算、存储、网络与云平台的深度协同,训练线性度超95%,为大模型训练推理提供强劲算力支撑。▲化工“数智”新模式。

华为云官方博客 664

【公共云三十问 之二十六】国计民生之钢铁:数智云如何淬炼中国钢铁新力量?

同时,构建云边端协同的统一架构,支撑集团总部与各生产基地两级协同发展——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现训推一体化的资源调度与高效协同,为钢铁行业的数智化转型构建了坚实的算力底座。层面,方案构建覆盖“工业数采→边缘IT/OT融合→统一数据湖→数据治理平台→数据应用”全链路的一站式数据治理与流通平台,打通生产现场与管理系统间的数据壁垒,让数据“采得到、流得动、用得好”,加速数据价值从生产现场向经营决策层流动释放。湘潭钢铁集团的钢铁数智云,是钢铁工业智能云建设的标杆案例。

华为云官方博客 526

LakeWatch——MRS 智能运维Agent

从资源池、队列、作业等多个维度,对集群CPU与内存资源进行精细化分析与对比,直观呈现不同时间段的空闲、满载等使用状态,识别资源浪费,指导治理优化,为扩缩容决策提供数据支撑。对HDFS存储进行多维度深度分析(目录、用户、用户组等),涵盖使用量、增量、文件大小分布及数据热度等指标,帮助快速识别增长较快的目录、长期未访问的文件,统计目录文件数量与小文件占比,评估HDFS总存储量与扩缩容需求,为存储治理与资源规划提供全面数据支撑。Agent主动巡检,识别异常趋势并提前预警,让运维从"事后处理"转向"事前预防"。

华为云官方博客 515

华为云专题文档发布:丰富的AI案例、选型指导和概念解读

发布 “云服务选型”、“云计算概念”专题,提供云服务选型指导,助您选择匹配业务的云服务,解读云计算相关概念,开启云上学习之路。开发者工具和文档专区上线,提供从学习、实践到反馈的全链路支持。帮助中心新增100余篇AI案例。

华为云官方博客 286

一个人,也能用AI做点“星东西”

华为云星耀创想者大赛-2026华为云OPC创意大赛等你来~

华为云官方博客 291

从需求到可执行工作项:MCP+Skill 让智能体规划真正落地

回顾整个体验,以前让智能体帮我拆需求,它是洋洋洒洒给我列了一大篇 Markdown,看着挺像那么回事,但最后还是得我一条条往 CodeArts Req 里搬,搬完再手动挂父子关系、排日期,拆需求五分钟,搬运两小时。现在好了,MCP 给智能体接上了"手",Skill 给它装上了"项目经理的脑子",一句话下去,34 个工作项连带排期、层级关系全给我建好了,甘特图一拉,齐刷刷都在两周内,节省了多少工作量啊,美滋滋。本次实操在码道代码智能体基础上,构建了一套"需求→可执行工作项"的自动化规划方案。

华为云官方博客 576

华为云码道「码力续航计划」更新!

✅上新GLM‑5.3‑Flash,高速响应,代码生成、工程解析、Agent调试高效输出。新增GLM‑5.3‑Flash福利模型,每日解锁1000万免费Tokens。● 本次活动共发放总量价值100万元Tokens,发完即止!把耗算力的编码重活,交给华为云码道代码智能体🚀🚀。● 每日额度准时刷新,当日清零、次日满血重置。✅复杂算法、大项目解析、批量代码生成随便跑。✅不用抠额度、不用算消耗,放开调试大胆迭代。✅无需额外操作,登录即送,直接切换模型使用。● 把算力交给码道,让撸码不再内耗👏🏻。

华为云官方博客 688

【公共云三十问 之二十四】国计民生之交通:交通云如何铺就数智通衢新坦途?

交通行业作为支撑实体经济的关键基础设施,涵盖公路、铁路、机场、港口、地铁等众多子领域,其中,公路网络作为综合交通运输体系的基础骨架,承担着全国超过70%的客货运量,其数字化、智能化转型的需求尤为迫切。方面,提供Agent开发框架、知识库管理、RAG工程、意图识别、静态应用编排及模型评测等能力,支持客户将行业知识、业务流程与AI能力深度融合,快速构建面向收费稽核、路网调度、应急处置等场景的智能应用。开发并实现落地应用,全面覆盖建设、管理、养护、运营、服务、安全、办公七大业务领域。

华为云官方博客 464

【公共云三十问 之二十五】国计民生之电力:电力云如何点亮数智电力新引擎?

方案构建了覆盖数据获取、质量评估到标准化处理的全链路能力。基于公共云服务商智算底座及气象大模型,通过时空图神经网络重新建模产流机制,中国华电建成超50TB多源融合数据集,突破时空建模与机理融合等五大关键技术,短期径流预测精度较传统机理模型提升5个百分点以上,实现15天中期径流预测精度超85%,推理效率达秒级。基于气象大模型的基础架构与预训练能力,客户可直接在大模型之上开展增量训练与微调,充分利用场站所在区域的高精度历史数据(如3公里、1公里分辨率),针对不同场站和区域的地形地貌与气候特征进行模型调优。

华为云官方博客 381
上一篇: GaussDB技术解读:应用无损透明(ALT)
下一篇: 开放同飞,华为云发布盘古大模型全域协同生态
华为云开发者联盟
华为云开发者联盟 企业官方账号 企业官方账号
博客等级 码龄10年 72万+粉丝 5985原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值