0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从WasmEdge运行环境读写Rust Wasm应用的时序数据

jf_wN0SrCdH 来源:Rust语言中文社区 2023-12-22 11:03 次阅读

WebAssembly (Wasm) 正在成为一个广受欢迎的编译目标,帮助开发者构建可迁移平台的应用。最近 Greptime 和 WasmEdge 协作,支持了在 WasmEdge 平台上的 Wasm 应用通过 MySQL 协议读写 GreptimeDB 中的时序数据。

什么是 WebAssembly

WebAssembly 是一种新的指令格式,同时具备了跨平台和接近原生机器代码的执行速度。通过将 C/C++ 或 Rust 代码编译成 WebAssembly ,可以在浏览器中提升程序的性能。而在浏览器外的其他运行环境,尤其是 CDN 或 IoT 的边缘端,我们也可以利用 WebAssembly 实现沙盒、动态加载的插件机制等高级的功能。

什么是 WasmEdge

WasmEdge 是 CNCF 的沙箱项目,提供上文提到的沙盒能力,允许开发者在 WebAssembly 标准的基础上,进一步扩展其能访问的资源和接口。例如,WasmEdge 为 Wasm 提供了额外的 TLS、网络能力和 AI 能力,大大丰富了使用场景。

WasmEdge GitHub 地址:

https://github.com/WasmEdge/WasmEdge

安装 GreptimeDB 和 WasmEdge

如果你已经安装了 GreptimeDB ,可以跳过这个步骤。

下载 GreptimeDB 并运行:

curl-Lhttps://github.com/GreptimeTeam/greptimedb/raw/develop/scripts/install.sh|sh
./greptimestandalonestart

安装 WasmEdge:

curl-sSfhttps://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh|bash-s

编写 GreptimeDB 的 WASM 应用

在 WasmEdge 中,我们可以使用 MySQL 协议,让 Rust 语言编写的应用程序连接到 GreptimeDB。

首先通过cargo new创建一个新的 Rust 项目,我们的编译目标将是wasm32-wasi,可以在项目根目录下创建.cargo/config.toml文件,指定默认编译目标,之后就无需在每次cargo build命令后专门指定--target了。

#.cargo/config.toml
[build]
target="wasm32-wasi"

编辑Cargo.toml增加依赖。mysql_async的应用需要tokio运行时,WasmEdge 维护了这两个库的修改版本,使他们能够编译成 WebAssembly 代码,并且运行到 WasmEdge 环境中。

[package]
name="greptimedb"
version="0.1.0"
edition="2021"

[dependencies]
mysql_async_wasi="0.31"
time="0.3"
tokio_wasi={version="1",features=["io-util","fs","net","time","rt","macros"]}

进一步编辑src/main.rs文件,加入数据库访问的逻辑。这段代码将演示:

通过环境变量读取数据库地址,并创建连接池;

执行 SQL 语句创建数据表;

插入数据;

查询数据。

定义数据结构:

#[derive(Debug)]
structCpuMetric{
hostname:String,
environment:String,
usage_user:f64,
usage_system:f64,
usage_idle:f64,
ts:i64,
}

implCpuMetric{
fnnew(
hostname:String,
environment:String,
usage_user:f64,
usage_system:f64,
usage_idle:f64,
ts:i64,
)->Self{
Self{
hostname,
environment,
usage_user,
usage_system,
usage_idle,
ts,
}
}

}

初始化数据库连接池:

usemysql_async::{
prelude::*,Opts,OptsBuilder,Pool,PoolConstraints,PoolOpts,Result,
};
usetime::PrimitiveDateTime;

fnget_url()->String{
ifletOk(url)=std::var("DATABASE_URL"){
letopts=Opts::from_url(&url).expect("DATABASE_URLinvalid");
ifopts
.db_name()
.expect("adatabasenameisrequired")
.is_empty()
{
panic!("databasenameisempty");
}
url
}else{
"mysql://root:pass@127.0.0.1:3306/mysql".into()
}
}


#[tokio::main(flavor="current_thread")]
asyncfnmain()->Result<()>{
//Alternative:The"easy"waywithadefaultconnectionpool
//letpool=Pool::from_url(&*get_url()).unwrap());
//letmutconn=pool.get_conn().await.unwrap();

//Belowwecreateacustomizedconnectionpool
letopts=Opts::from_url(&*get_url()).unwrap();
letbuilder=OptsBuilder::from_opts(opts);
//Theconnectionpoolwillhaveaminof1andmaxof2connections.
letconstraints=PoolConstraints::new(1,2).unwrap();
letpool_opts=PoolOpts::default().with_constraints(constraints);

letpool=Pool::new(builder.pool_opts(pool_opts));
letmutconn=pool.get_conn().await.unwrap();



Ok(())
}

创建数据表:

//Createtableifnotexists
r"CREATETABLEIFNOTEXISTSwasmedge_example_cpu_metrics(
hostnameSTRING,
environmentSTRING,
usage_userDOUBLE,
usage_systemDOUBLE,
usage_idleDOUBLE,
tsTIMESTAMP,
TIMEINDEX(ts),
PRIMARYKEY(hostname,environment)
);"
.ignore(&mutconn)
.await?;

插入数据:

 letmetrics=vec![
CpuMetric::new(
"host0".into(),
"test".into(),
32f64,
3f64,
4f64,
1680307200050,
),
CpuMetric::new(
"host1".into(),
"test".into(),
29f64,
32f64,
50f64,
1680307200050,
),
CpuMetric::new(
"host0".into(),
"test".into(),
32f64,
3f64,
4f64,
1680307260050,
),
CpuMetric::new(
"host1".into(),
"test".into(),
29f64,
32f64,
50f64,
1680307260050,
),
CpuMetric::new(
"host0".into(),
"test".into(),
32f64,
3f64,
4f64,
1680307320050,
),
CpuMetric::new(
"host1".into(),
"test".into(),
29f64,
32f64,
50f64,
1680307320050,
),
];

r"INSERTINTOwasmedge_example_cpu_metrics(hostname,environment,usage_user,usage_system,usage_idle,ts)
VALUES(:hostname,:environment,:usage_user,:usage_system,:usage_idle,:ts)"
.with(metrics.iter().map(|metric|{
params!{
"hostname"=>&metric.hostname,
"environment"=>&metric.environment,
"usage_user"=>metric.usage_user,
"usage_system"=>metric.usage_system,
"usage_idle"=>metric.usage_idle,
"ts"=>metric.ts,
}
}))
.batch(&mutconn)

.await?;

查询数据:

letloaded_metrics="SELECT*FROMwasmedge_example_cpu_metrics"
.with(())
.map(
&mutconn,
|(hostname,environment,usage_user,usage_system,usage_idle,raw_ts):(
String,
String,
f64,
f64,
f64,
PrimitiveDateTime,
)|{
letts=raw_ts.assume_utc().unix_timestamp()*1000;
CpuMetric::new(
hostname,
environment,
usage_user,
usage_system,
usage_idle,
ts,
)
},
)
.await?;

println!("{:?}",loaded_metrics);

WasmEdge 团队提供的tokio和mysql_async库与原始版本编程接口完全一致,因此可以无缝地将普通 Rust 应用切换到 WebAssembly 平台上。

编译这个项目,我们可以获得 greptimedb.wasm 文件:

cargobuild
ls-lhtarget/wasm32-wasi/debug/greptimedb.wasm

通过 WasmEdge 运行我们的程序:

wasmedge--env"DATABASE_URL=mysql://localhost:4002/public"target/wasm32-wasi/debug/greptimedb.wasm

上面这段示例程序已经纳入了 WasmEdge 的数据库使用示例,你可以在 GitHub 仓库找到完整的代码:

https://github.com/WasmEdge/wasmedge-db-examples/tree/main/greptimedb。

总结

WasmEdge 为 WebAssembly 应用提供了更多的扩展能力。如果你也将应用部署在 WebAssembly 环境里,未来我们还可以使用 OpenTelemetry SDK 采集指标数据直接存储到 GreptimeDB 。现在就下载 GreptimeDB 或开通 GreptimeCloud 实例运行上面的例子吧。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 时序
    +关注

    关注

    5

    文章

    385

    浏览量

    37268
  • MySQL
    +关注

    关注

    1

    文章

    801

    浏览量

    26433
  • 编译
    +关注

    关注

    0

    文章

    652

    浏览量

    32800
  • GitHub
    +关注

    关注

    3

    文章

    466

    浏览量

    16380
  • Rust
    +关注

    关注

    1

    文章

    228

    浏览量

    6566

原文标题:从 WasmEdge 运行环境读写 Rust Wasm 应用的时序数据

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何在Rust读写文件

    见的内存安全问题和数据竞争问题。 在Rust中,读写文件是一项非常常见的任务。本教程将介绍如何在Rust读写文件,包括基础用法和进阶用法。
    的头像 发表于 09-20 10:57 1965次阅读

    时序数据库HiTSDB的深度解析!

    深度解读!时序数据库HiTSDB:分布式流式聚合引擎
    发表于 07-22 13:22

    多片段时序数据建模预测实践资料分享

    时序数据建模分析已经有很多相关的应用了,在这个领域里面LSTM网络绝对是占据着非常重要的作用,自从LSTM网络提出以来,陆陆续续又出现了很多相关的变种网络,传统的时序建模工作主要是基于一个指定的时序数据
    发表于 06-30 07:52

    关于时序数据库的内容

    简介: 这是一篇无法一口气读完的、文字过万[正文字数14390]的长文,这是一个无法中途不上厕所就看完的、关于时序数据库的视频[时长111分钟]分享的文字整理..大家好,很开心能够和大家一起交流时序数据
    发表于 07-12 08:00

    什么是时序数据库?

    数据库(TSDB)是一个为了用于处理时间序列数据而优化的软件系统,其按时间数值或时间范围进行索引。时序数据库增长趋势时序数据2014年开
    发表于 07-12 08:35

    Wasm软件生态系统安全分析

    ,如C、C++、Rust、Go、Java、C#等几乎所有主流高级语言都可以被编译到Wasm,所有的主流浏览器也均支持Wasm。此外业界也实现了很多独立的Wasm虚拟机(
    发表于 09-05 15:29

    TableStore时序数据存储 - 架构篇

    摘要: 背景 随着近几年物联网的发展,时序数据迎来了一个不小的爆发。DB-Engines上近两年的数据库类型增长趋势来看,时序数据库的增长是非常迅猛的。在去年我花了比较长的时间去了解
    发表于 08-08 16:17 571次阅读
    TableStore<b class='flag-5'>时序数据</b>存储 - 架构篇

    时序数据库的前世今生

    的频频发声,正说明各家企业已经迫不及待的拥抱物联网时代的到来。 本文会时序数据库的基本概念、应用场景、需求与能力等方面一一展开,带你了解时序数据库的前世今生。 01 应用场景 时序数据
    的头像 发表于 12-17 17:51 3554次阅读

    华为时序数据库为智慧健康养老行业贡献应用之道

    随着 IoT 技术的快速发展,物联网设备产生的数据呈爆炸式增长。这些数据通常随时间产生,称之为时序数据。这样的一种专门用于管理时序数据数据
    的头像 发表于 11-07 15:10 5852次阅读

    华为PB级时序数据库Gauss DB,助力海量数据处理

      近年来,时序数据的应用更为广泛,包括物联网、金融领域、监控领域、医学领域、农业生产领域等各方面,都在大量使用时序数据,通过数据来研究对象的趋势性、规律性、异常性;并且在 5G 与人工智能的浪潮下
    的头像 发表于 10-15 19:15 1096次阅读
    华为PB级<b class='flag-5'>时序数据</b>库Gauss DB,助力海量<b class='flag-5'>数据</b>处理

    WasmEdge增加了Tokio支持

    WasmEdge 成功地移植了 tokio(一个 Rust 异步运行时)到 Wasm:https://github.com/WasmEdge
    的头像 发表于 12-05 11:55 802次阅读

    物联网场景海量时序数据存储与处理的关键技术

    时序数据是随时间不断产生的一系列数据,例如持续监控的气象变化数据、股市交易记录、应用监控数据等,通常一个时序数据点可以由
    发表于 12-27 11:58 2240次阅读

    涂鸦推出NekoDB时序数据库,助力全球客户实现低成本部署

    随着IoT技术逐渐成熟,众多设备产出的数据呈现指数级增长。企业亟需用行之有效的方式管理海量时序数据。由此,各类时序数据库开始成为市场宠儿。与市场需求相悖的是,时序数据库水平参差不齐。纵
    的头像 发表于 07-24 10:08 2062次阅读
    涂鸦推出NekoDB<b class='flag-5'>时序数据</b>库,助力全球客户实现低成本部署

    什么是wasm组件?使用Rust开发wasm组件实战

    wasm 全称 WebAssembly,是通过虚拟机的方式,可以在服务端、客户端如浏览器等环境执行的二进制程序。它有速度快、效率高、可移植的特点。
    的头像 发表于 09-22 11:30 4365次阅读
    什么是<b class='flag-5'>wasm</b>组件?使用<b class='flag-5'>Rust</b>开发<b class='flag-5'>wasm</b>组件实战

    时序数据库是什么?时序数据库的特点

    时序数据库是一种在处理时间序列数据方面具有高效和专门化能力的数据库。它主要用于存储和处理时间序列数据,比如传感器数据、监控
    的头像 发表于 04-26 16:02 593次阅读