Rust与Redis数据库开发实战:构建高性能会话管理系统

Rust与Redis数据库开发实战:构建高性能会话管理系统

Rust与Redis数据库开发实战:构建高性能会话管理系统

在这里插入图片描述

一、引言

💡Redis是一款高性能的内存数据库,它支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,具有读写速度快、内存占用少、跨平台等特点,非常适合开发缓存、消息队列、会话管理、实时数据分析等应用。

Rust语言以其内存安全、高性能和良好的工具链支持,成为开发Redis应用的理想选择。Rust生态系统中提供了多个优秀的Redis库,其中redis-rs是最成熟、最流行的一个。redis-rs提供了安全、易用的API,支持Redis的全部功能,包括事务处理、管道操作、发布订阅等。

二、开发环境搭建

2.1 安装Redis

Redis通常已经预装在大多数操作系统中,你可以通过以下命令检查是否安装:

# 检查Redis版本 redis-cli --version

如果没有安装,可以通过以下命令安装:

macOS
# 使用Homebrew安装 brew install redis # 启动Redis服务 brew services start redis 
Ubuntu/Debian
# 使用apt-get安装sudoapt-get update sudoapt-getinstall-y redis-server # 启动Redis服务sudo systemctl start redis-server 
Windows

下载Redis官方预编译二进制文件:https://github.com/microsoftarchive/redis/releases,解压后将redis-cli.exeredis-server.exe添加到系统路径中。

2.2 创建Rust项目

使用Cargo创建一个新的Rust项目:

# 创建项目cargo new rust-redis-session cd rust-redis-session # 查看项目结构ls-la

2.3 安装redis-rs依赖

Cargo.toml中添加redis-rs依赖:

[package] name = "rust-redis-session" version = "0.1.0" edition = "2021" [dependencies] redis = { version = "0.25", features = ["tokio-comp"] } tokio = { version = "1.0", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.0", features = ["v4"] } chrono = { version = "0.4", features = ["serde"] } thiserror = "1.0" clap = { version = "4.5", features = ["derive"] } 

依赖说明:

  • redis-rs:Redis的Rust绑定,支持异步操作。
  • tokio:Rust的异步运行时。
  • serde:数据序列化/反序列化库。
  • serde_json:JSON数据序列化/反序列化库。
  • uuid:UUID生成库。
  • chrono:日期和时间处理库。
  • thiserror:自定义错误类型库。
  • clap:命令行参数解析库。

三、Redis基本操作

3.1 连接Redis

使用redis-rs连接Redis:

// src/main.rsuseredis::RedisError;usestd::env;asyncfnconnect_redis()->Result<redis::Client,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let client =redis::Client::open(redis_url)?;println!("Successfully connected to Redis");Ok(client)}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;Ok(())}

3.2 字符串操作

使用字符串操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnstring_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 设置值 con.set("username","admin").await?;println!("Successfully set username: admin");// 获取值let username:String= con.get("username").await?;println!("Successfully got username: {}", username);// 设置值并指定过期时间 con.set_ex("token","abc123",3600).await?;println!("Successfully set token: abc123 (expires in 3600 seconds)");// 获取值并检查过期时间let token:Option<String>= con.get("token").await?;ifletSome(token)= token {println!("Successfully got token: {}", token);}else{println!("Token not found");}Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;string_example(&client).await?;Ok(())}

3.3 哈希操作

使用哈希操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnhash_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 设置哈希值 con.hset("user:1","name","admin").await?; con.hset("user:1","email","[email protected]").await?; con.hset("user:1","password","password123").await?;println!("Successfully set user:1");// 获取哈希值let name:String= con.hget("user:1","name").await?;let email:String= con.hget("user:1","email").await?;let password:String= con.hget("user:1","password").await?;println!("Successfully got user:1");println!("Name: {}", name);println!("Email: {}", email);println!("Password: {}", password);// 获取所有哈希字段和值let user:Vec<(String,String)>= con.hgetall("user:1").await?;println!("Successfully got user:1 fields and values: {:?}", user);// 删除哈希字段 con.hdel("user:1","password").await?;println!("Successfully deleted user:1 password");Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;hash_example(&client).await?;Ok(())}

3.4 列表操作

使用列表操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnlist_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向列表添加元素 con.lpush("tasks","Learn Rust").await?; con.lpush("tasks","Learn Redis").await?; con.lpush("tasks","Build Project").await?;println!("Successfully added tasks to list");// 获取列表长度let length:i64= con.llen("tasks").await?;println!("Tasks list length: {}", length);// 获取列表元素let tasks:Vec<String>= con.lrange("tasks",0,-1).await?;println!("Tasks list: {:?}", tasks);// 从列表左侧弹出元素let task:String= con.lpop("tasks").await?;println!("Successfully popped task from left: {}", task);// 从列表右侧弹出元素let task:String= con.rpop("tasks").await?;println!("Successfully popped task from right: {}", task);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;list_example(&client).await?;Ok(())}

3.5 集合操作

使用集合操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnset_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向集合添加元素 con.sadd("tags","Rust").await?; con.sadd("tags","Redis").await?; con.sadd("tags","Web").await?;println!("Successfully added tags to set");// 获取集合元素let tags:Vec<String>= con.smembers("tags").await?;println!("Tags set: {:?}", tags);// 检查元素是否存在let exists:bool= con.sismember("tags","Rust").await?;println!("Tag Rust exists: {}", exists);// 删除元素 con.srem("tags","Web").await?;println!("Successfully removed tag Web from set");Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;set_example(&client).await?;Ok(())}

3.6 有序集合操作

使用有序集合操作存储和获取数据:

// src/main.rsuseredis::AsyncCommands;useredis::RedisError;asyncfnzset_example(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 向有序集合添加元素 con.zadd("scores","user1",90).await?; con.zadd("scores","user2",85).await?; con.zadd("scores","user3",95).await?;println!("Successfully added scores to zset");// 获取有序集合元素let scores:Vec<(String,i32)>= con.zrange_withscores("scores",0,-1).await?;println!("Scores zset: {:?}", scores);// 获取有序集合元素并按分数降序排序let scores_desc:Vec<(String,i32)>= con.zrevrange_withscores("scores",0,-1).await?;println!("Scores zset (desc): {:?}", scores_desc);// 获取元素的分数let score:i32= con.zscore("scores","user1").await?;println!("User1 score: {}", score);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;zset_example(&client).await?;Ok(())}

四、实战项目:高性能会话管理系统

4.1 项目概述

开发一个高性能的会话管理系统,支持以下功能:

  • 用户登录:验证用户名和密码
  • 会话创建:创建新的会话
  • 会话验证:验证会话的有效性
  • 会话过期:自动清理过期的会话
  • 会话统计:统计会话数量

4.2 数据结构设计

使用Redis的字符串、哈希、集合等数据结构存储会话数据:

  • 会话ID:使用UUID生成
  • 会话数据:存储在哈希中,包括用户ID、用户名、过期时间等
  • 会话集合:存储所有有效的会话ID
  • 用户会话映射:存储用户ID到会话ID的映射

4.3 代码实现

4.3.1 定义会话结构体
// src/session.rsusechrono::{DateTime,Utc};useserde::{Deserialize,Serialize};useuuid::Uuid;#[derive(Debug, Clone, Serialize, Deserialize)]pubstructSession{pub id:String,pub user_id:String,pub username:String,pub created_at:DateTime<Utc>,pub expires_at:DateTime<Utc>,}implSession{pubfnnew(user_id:String, username:String, expires_in:i64)->Self{let id =Uuid::new_v4().to_string();let created_at =Utc::now();let expires_at = created_at +chrono::Duration::seconds(expires_in);Session{ id, user_id, username, created_at, expires_at,}}pubfnis_expired(&self)->bool{Utc::now()>self.expires_at }}
4.3.2 定义会话管理结构体
// src/session.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;usecrate::session::Session;#[derive(Debug)]pubstructSessionManager{ client:redis::Client, prefix:String, default_expires_in:i64,}implSessionManager{pubfnnew(client:redis::Client, prefix:String, default_expires_in:i64)->Self{SessionManager{ client, prefix, default_expires_in,}}pubasyncfncreate_session(&self, user_id:String, username:String)->Result<Session,RedisError>{let session =Session::new(user_id, username,self.default_expires_in);letmut con =self.client.get_async_connection().await?;// 存储会话数据let session_key =format!("{}:{}",self.prefix, session.id); con.hset(&session_key,"user_id",&session.user_id).await?; con.hset(&session_key,"username",&session.username).await?; con.hset(&session_key,"created_at",&session.created_at.to_rfc3339()).await?; con.hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).await?; con.expire(&session_key,self.default_expires_in).await?;println!("Successfully created session: {}", session.id);// 添加到会话集合let sessions_key =format!("{}:sessions",self.prefix); con.sadd(&sessions_key,&session.id).await?;println!("Successfully added session to sessions set: {}", session.id);// 添加到用户会话映射let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); con.sadd(&user_sessions_key,&session.id).await?;println!("Successfully added session to user sessions: {}", session.id);Ok(session)}pubasyncfnget_session(&self, session_id:&str)->Result<Option<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;let session_key =format!("{}:{}",self.prefix, session_id);// 获取会话数据let session_data:Option<HashMap<String,String>>= con.hgetall(&session_key).await?;ifletSome(session_data)= session_data {let session =Session{ id: session_id.to_string(), user_id: session_data.get("user_id").unwrap_or(&"".to_string()).to_string(), username: session_data.get("username").unwrap_or(&"".to_string()).to_string(), created_at:DateTime::parse_from_rfc3339(session_data.get("created_at").unwrap_or(&"".to_string())).unwrap().with_timezone(&Utc), expires_at:DateTime::parse_from_rfc3339(session_data.get("expires_at").unwrap_or(&"".to_string())).unwrap().with_timezone(&Utc),};// 检查会话是否过期if session.is_expired(){self.delete_session(session_id).await?;Ok(None)}else{Ok(Some(session))}}else{Ok(None)}}pubasyncfndelete_session(&self, session_id:&str)->Result<(),RedisError>{letmut con =self.client.get_async_connection().await?;let session_key =format!("{}:{}",self.prefix, session_id);// 获取会话数据以删除用户会话映射let session_data:Option<HashMap<String,String>>= con.hgetall(&session_key).await?;ifletSome(session_data)= session_data {let user_id = session_data.get("user_id").unwrap_or(&"".to_string()).to_string();let user_sessions_key =format!("{}:user:{}",self.prefix, user_id); con.srem(&user_sessions_key, session_id).await?;println!("Successfully removed session from user sessions: {}", session_id);}// 删除会话数据 con.del(&session_key).await?;println!("Successfully deleted session data: {}", session_id);// 从会话集合中删除let sessions_key =format!("{}:sessions",self.prefix); con.srem(&sessions_key, session_id).await?;println!("Successfully removed session from sessions set: {}", session_id);Ok(())}pubasyncfnget_user_sessions(&self, user_id:&str)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;let user_sessions_key =format!("{}:user:{}",self.prefix, user_id);// 获取用户的所有会话IDlet session_ids:Vec<String>= con.smembers(&user_sessions_key).await?;letmut sessions =Vec::new();// 获取每个会话的数据for session_id in session_ids {ifletSome(session)=self.get_session(&session_id).await?{ sessions.push(session);}}Ok(sessions)}pubasyncfnclean_expired_sessions(&self)->Result<(),RedisError>{letmut con =self.client.get_async_connection().await?;let sessions_key =format!("{}:sessions",self.prefix);// 获取所有会话IDlet session_ids:Vec<String>= con.smembers(&sessions_key).await?;for session_id in session_ids {ifletSome(session)=self.get_session(&session_id).await?{if session.is_expired(){self.delete_session(&session_id).await?;}}}println!("Successfully cleaned expired sessions");Ok(())}}
4.3.3 定义用户认证模块
// src/auth.rsuseserde::{Deserialize,Serialize};#[derive(Debug, Clone, Serialize, Deserialize)]pubstructUser{pub id:String,pub username:String,pub password:String,}implUser{pubfnnew(id:String, username:String, password:String)->Self{User{ id, username, password }}}#[derive(Debug, Clone)]pubstructAuthManager{ users:Vec<User>,}implAuthManager{pubfnnew(users:Vec<User>)->Self{AuthManager{ users }}pubfnauthenticate(&self, username:&str, password:&str)->Option<User>{self.users.iter().find(|user| user.username == username && user.password == password).cloned()}}
4.3.4 定义命令行界面
// src/cli.rsuseclap::Parser;useserde::{Deserialize,Serialize};#[derive(Parser, Debug)]#[command(name = "rust-redis-session")]#[command(about = "A high-performance session management system written in Rust")]structArgs{#[command(subcommand)] command:Commands,}#[derive(clap::Subcommand, Debug)]enumCommands{#[command(about = "User login")]Login{#[arg(short, long, help = "Username")] username:String,#[arg(short, long, help = "Password")] password:String,},#[command(about = "Get session by ID")]Get{#[arg(short, long, help = "Session ID")] session_id:String,},#[command(about = "Delete session by ID")]Delete{#[arg(short, long, help = "Session ID")] session_id:String,},#[command(about = "Get user sessions")]User{#[arg(short, long, help = "User ID")] user_id:String,},#[command(about = "Clean expired sessions")]Clean,}
4.3.5 定义主函数
// src/main.rsuseredis::RedisError;usestd::env;usecrate::auth::AuthManager;usecrate::auth::User;usecrate::cli::Args;usecrate::session::SessionManager;asyncfnconnect_redis()->Result<redis::Client,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let client =redis::Client::open(redis_url)?;println!("Successfully connected to Redis");Ok(client)}asyncfnlogin(session_manager:&SessionManager, auth_manager:&AuthManager, username:&str, password:&str)->Result<(),RedisError>{match auth_manager.authenticate(username, password){Some(user)=>{let session = session_manager.create_session(user.id, user.username).await?;println!("Successfully logged in");println!("Session ID: {}", session.id);println!("Expires at: {}", session.expires_at);}None=>{println!("Invalid username or password");}}Ok(())}asyncfnget_session(session_manager:&SessionManager, session_id:&str)->Result<(),RedisError>{match session_manager.get_session(session_id).await?{Some(session)=>{println!("Successfully got session: {}", session.id);println!("User ID: {}", session.user_id);println!("Username: {}", session.username);println!("Created at: {}", session.created_at);println!("Expires at: {}", session.expires_at);}None=>{println!("Session not found or expired");}}Ok(())}asyncfndelete_session(session_manager:&SessionManager, session_id:&str)->Result<(),RedisError>{ session_manager.delete_session(session_id).await?;println!("Successfully deleted session: {}", session_id);Ok(())}asyncfnget_user_sessions(session_manager:&SessionManager, user_id:&str)->Result<(),RedisError>{let sessions = session_manager.get_user_sessions(user_id).await?;println!("Successfully got user sessions: {}", user_id);for session in sessions {println!("Session ID: {}", session.id);println!("Created at: {}", session.created_at);println!("Expires at: {}", session.expires_at);println!("---");}Ok(())}asyncfnclean_expired_sessions(session_manager:&SessionManager)->Result<(),RedisError>{ session_manager.clean_expired_sessions().await?;Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let args =Args::parse();let client =connect_redis().await?;let session_manager =SessionManager::new(client,"session".to_string(),3600);let users =vec![User::new("1","admin","password123"),User::new("2","user1","password456"),User::new("3","user2","password789"),];let auth_manager =AuthManager::new(users);match args.command {Commands::Login{ username, password }=>{login(&session_manager,&auth_manager,&username,&password).await?;}Commands::Get{ session_id }=>{get_session(&session_manager,&session_id).await?;}Commands::Delete{ session_id }=>{delete_session(&session_manager,&session_id).await?;}Commands::User{ user_id }=>{get_user_sessions(&session_manager,&user_id).await?;}Commands::Clean=>{clean_expired_sessions(&session_manager).await?;}}Ok(())}

4.4 测试项目

运行会话管理系统:

# 编译项目cargo build # 启动Redis服务器(如果未启动) redis-server # 用户登录cargo run -- login --username admin --password password123 # 获取会话cargo run -- get --session-id <session-id># 删除会话cargo run -- delete --session-id <session-id># 获取用户会话cargo run -- user --user-id 1# 清理过期会话cargo run -- clean 

五、性能优化

5.1 使用连接池

使用连接池管理Redis连接:

// src/connection_pool.rsuseredis::RedisError;use r2d2;user2d2_redis::RedisConnectionManager;asyncfncreate_connection_pool()->Result<r2d2::Pool<RedisConnectionManager>,RedisError>{let redis_url =env::var("REDIS_URL").unwrap_or_else(|_|"redis://127.0.0.1:6379".to_string());let manager =RedisConnectionManager::new(redis_url)?;let pool =r2d2::Pool::builder().max_size(10).build(manager)?;println!("Successfully created Redis connection pool");Ok(pool)}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let pool =create_connection_pool().await?;Ok(())}

5.2 使用批量操作

使用批量操作提升性能:

// src/session.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;implSessionManager{pubasyncfncreate_sessions(&self, users:Vec<(String,String)>)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;letmut sessions =Vec::new();for(user_id, username)in users {let session =Session::new(user_id, username,self.default_expires_in);let session_key =format!("{}:{}",self.prefix, session.id); con.hset(&session_key,"user_id",&session.user_id).await?; con.hset(&session_key,"username",&session.username).await?; con.hset(&session_key,"created_at",&session.created_at.to_rfc3339()).await?; con.hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).await?; con.expire(&session_key,self.default_expires_in).await?;let sessions_key =format!("{}:sessions",self.prefix); con.sadd(&sessions_key,&session.id).await?;let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); con.sadd(&user_sessions_key,&session.id).await?; sessions.push(session);}Ok(sessions)}}

5.3 使用管道操作

使用管道操作提升性能:

// src/session.rsuseredis::pipe;useredis::RedisError;implSessionManager{pubasyncfncreate_sessions_pipeline(&self, users:Vec<(String,String)>)->Result<Vec<Session>,RedisError>{letmut con =self.client.get_async_connection().await?;letmut pipe =pipe();letmut sessions =Vec::new();for(user_id, username)in users {let session =Session::new(user_id, username,self.default_expires_in);let session_key =format!("{}:{}",self.prefix, session.id);let sessions_key =format!("{}:sessions",self.prefix);let user_sessions_key =format!("{}:user:{}",self.prefix, session.user_id); pipe .hset(&session_key,"user_id",&session.user_id).ignore().hset(&session_key,"username",&session.username).ignore().hset(&session_key,"created_at",&session.created_at.to_rfc3339()).ignore().hset(&session_key,"expires_at",&session.expires_at.to_rfc3339()).ignore().expire(&session_key,self.default_expires_in).ignore().sadd(&sessions_key,&session.id).ignore().sadd(&user_sessions_key,&session.id).ignore(); sessions.push(session);} pipe.query_async(&mut con).await?;Ok(sessions)}}

5.4 优化缓存策略

使用缓存策略优化性能:

// src/cache.rsuseredis::AsyncCommands;useredis::RedisError;usestd::collections::HashMap;asyncfnoptimize_cache(client:&redis::Client)->Result<(),RedisError>{letmut con = client.get_async_connection().await?;// 使用set命令代替hset命令 con.set("user:1:name","admin").await?; con.set("user:1:email","[email protected]").await?;println!("Successfully set user data using set commands");// 使用get命令代替hget命令let name:String= con.get("user:1:name").await?;let email:String= con.get("user:1:email").await?;println!("Successfully got user data using get commands: name={}, email={}", name, email);Ok(())}#[tokio::main]asyncfnmain()->Result<(),RedisError>{let client =connect_redis().await?;optimize_cache(&client).await?;Ok(())}

六、总结

6.1 技术栈

  • Rust:开发语言
  • redis-rs:Redis的Rust绑定,支持异步操作
  • tokio:Rust的异步运行时
  • serde:数据序列化/反序列化库
  • uuid:UUID生成库
  • chrono:日期和时间处理库
  • thiserror:自定义错误类型库
  • clap:命令行参数解析库

6.2 核心功能

  • 用户登录:验证用户名和密码
  • 会话创建:创建新的会话
  • 会话验证:验证会话的有效性
  • 会话过期:自动清理过期的会话
  • 会话统计:统计会话数量

6.3 未来改进方向

  • 添加会话刷新功能:在会话即将过期时自动刷新会话的过期时间
  • 添加会话统计功能:统计会话的创建时间、过期时间、访问频率等
  • 添加会话限制功能:限制用户的会话数量
  • 添加会话加密功能:对会话数据进行加密存储
  • 添加会话备份功能:定期备份会话数据到磁盘

通过本章的学习,读者可以深入理解Rust与Redis数据库开发的工作原理和实现方法,并在实际项目中应用这些技术。同时,本章也介绍了如何优化Redis操作的性能,帮助读者构建高性能的应用。

Read more

【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优

【SpringAI】第四弹:深入解析 Rag 检索增强工作流程、最佳实践和调优

本节重点 以 Spri‏ng AI 框架为例,‏学习 RAG 知识库应‏用开发的核心特性和高级‏知识点,并且掌握 RA‌G 最佳实践和调优技巧。 具体内容包括: * RAG 核心特性 * 文档收集和切割(ETL) * 向量转换和存储(向量数据库) * 文档过滤和检索(文档检索器) * 查询增强和关联(上下文查询增强器) * RAG 最佳实践和调优 * RAG 高级知识 * 检索策略 * 大模型幻觉 * 高级 RAG 架构 一、RAG 核心特性 Rag 检索增强工作流程 一、建立索引 (1) 文档预处理和切割 ETL 首先对文档进行结构优化,内容清洗,也就是让文档的每一个部分的内容,都有一个标题,来划分每个部分的内容,

By Ne0inhk
别再手动调优了!KingbaseES连接条件下推自动拯救慢 SQL

别再手动调优了!KingbaseES连接条件下推自动拯救慢 SQL

告别SQL性能焦虑:金仓数据库“连接条件下推”的性能魔法 你是否遇到过这样的场景:一个看似复杂的SQL,在测试环境运行飞快,一到生产环境就“卡死”,一查执行计划,发现子查询生成了一个巨大的中间结果集,导致后续操作全部陷入性能泥潭? 如果你正被此类场景困扰,那么,是时候认识一项改变游戏规则的技术:金仓数据库(KingbaseES)「基于代价的连接条件下推」。它不仅是技术优化,更是应对复杂业务查询的“性能终结者”。 一、 为什么你的复杂SQL会“爆内存”? 在金融、政务等复杂业务系统中,为了逻辑清晰,SQL常常被写成这样: SELECT * FROM (SELECT DISTINCT * FROM 巨表_A) AS 子查询结果, 筛选表_B WHERE 子查询结果.关键ID = 筛选表_B.关键ID AND 筛选表_B.过滤字段 = '

By Ne0inhk

LangChain: 从 LLM 调用到 Agent 架构

一、为什么要用 LangChain? 自从 OpenAI 推出 ChatGPT 之后,大模型能力迅速普及。越来越多的开发者开始将 LLM 接入业务系统,但很快会遇到三个现实问题: 1、模型接口不统一 —— 今天用 OpenAI,明天换国内模型,代码要大改 2、Prompt 难管理 —— 提示词到处拼字符串,无法版本控制 3、业务流程复杂 —— RAG、Agent、多工具调用,全是胶水代码 这时候,LangChain 就登场了。 LangChain 本质是一套 “面向大模型应用开发的工程化框架”,它把模型调用、Prompt 管理、知识检索、流程编排、Agent 调度全部抽象成可组合模块,让你像搭积木一样构建 AI 应用。 二、LangChain 架构全景 LangChain

By Ne0inhk
Flutter 组件 short_uuids 适配鸿蒙 HarmonyOS 实战:唯一标识微缩技术,构建高性能短 ID 生成与分布式索引架构

Flutter 组件 short_uuids 适配鸿蒙 HarmonyOS 实战:唯一标识微缩技术,构建高性能短 ID 生成与分布式索引架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 short_uuids 适配鸿蒙 HarmonyOS 实战:唯一标识微缩技术,构建高性能短 ID 生成与分布式索引架构 前言 在鸿蒙(OpenHarmony)生态迈向万物互联、涉及海量离线资源标识、蓝牙广播载荷(BLE Payload)及二维码数据极限压缩的背景下,如何生成既能保留 UUID 强随机性、又能极大缩减字符长度的唯一标识符,已成为优化存储与通讯效率的“空间必修课”。在鸿蒙设备这类强调分布式软总线传输与每一字节功耗敏感的环境下,如果应用依然直接传输长度达 36 字符的标准 UUID,由于由于有效载荷溢出,极易由于由于传输协议限制导致数据截断或多次分包带来的延迟。 我们需要一种能够实现高进制转换、支持双向编解码且具备低碰撞概率的短 ID 生成方案。 short_uuids 为 Flutter 开发者引入了将标准 UUID 转化为短格式字符串的高性能算法。它利用

By Ne0inhk