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

Cursor完全卸载与重装指南:go-cursor-help辅助工具

Cursor完全卸载与重装指南:go-cursor-help辅助工具 【免费下载链接】go-cursor-help解决Cursor在免费订阅期间出现以下提示的问题: You've reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to pro. We have this limit in place to prevent abuse. Please let us know if you believe this is a mistake. 项目地址: https://gitcode.com/GitHub_

By Ne0inhk
2025年PostgreSQL 详细安装教程(windows)

2025年PostgreSQL 详细安装教程(windows)

前言 PostgreSQL 是一个功能强大的开源关系型数据库管理系统(ORDBMS),以下是对它的全面介绍: 基本概况 * 名称:通常简称为 "Postgres" * 类型:对象-关系型数据库管理系统 * 许可:开源,采用类MIT许可证 * 首次发布:1996年(起源于1986年的POSTGRES项目) * 最新版本:PostgreSQL 16(截至2023年9月发布) 核心特性 1. 标准兼容性 * 完全符合ACID(原子性、一致性、隔离性、持久性) * 高度兼容SQL标准 2. 高级功能 * 复杂查询 * 外键 * 触发器 * 可更新视图 * 事务完整性 * 多版本并发控制(MVCC) 3. 扩展性 * 支持自定义数据类型 * 自定义函数 * 使用不同编程语言编写代码(如PL/pgSQL, PL/Python,

By Ne0inhk
在vsCode中使用node.js调试js代码时报错3221225477

在vsCode中使用node.js调试js代码时报错3221225477

我们在第一次使用node.js时,可能会遇到版本不兼容的问题,在使用时就会报错。推荐下载nodejs使用nvm下载 Nvm下载  选择nvm-setup.zip进行下载,下载好了后,打卡按照步骤点击下载(环境变量会自动配置,包括后面nodejs配置环境),下载完成后按win+r输入cmd 在命令行界面输入 nvm list available 查看可下载的nodejs版本 推荐下载18.20.4版本的,大部分都兼容,在命令行界面输入 nvm install 18.20.4  同样你可以在nvm中下载更多版本的 nvm use 18.20.4 使用use后面跟上你想切换的版本就可以切换使用的nodejs版本了 这样就解决了在使用vscode中nodejs会报3221225477错的问题了

By Ne0inhk
小白必看:MoE 架构详解(大模型入门指南),一篇搞定!

小白必看:MoE 架构详解(大模型入门指南),一篇搞定!

一、概念解读 MoE,即混合专家模型(Mixture of Experts),它的核心概念可以用 “术业有专攻” 来简单概括。想象一下,你要解决一系列复杂的问题,有一个全能型的智者,他什么都懂,但当问题数量众多且繁杂时,他处理起来可能会有些吃力,效率也不高。而 MoE 架构就像是组建了一个专家团队,每个专家都擅长某一特定领域,当问题出现时,能够迅速找到对应的专家来解决,大大提高了解决问题的效率。 MoE并非把整个网络应用于每一个输入,而是去学习一种计算成本较低的映射函数,通过这个函数来判断网络中的哪些部分(也就是哪些专家)能够最高效地处理给定的输入。此外,MoE模型中还配备了一个路由器,它的作用是有选择地激活完成给定任务所需要的特定专家,而不是针对每一项任务都激活整个神经网络。 混合专家(MoE)模型的专家(Expert)是什么?专家(Expert)是训练好的子网络(神经网络或层),通常是一个独立的前馈神经网络(FFNN),也可以是更复杂的网络结构。 MoE模型将一个复杂的任务拆分成多个子任务,每个子任务都交给一个专门的“专家”来处理。这些专家各自拥有独特的专长,

By Ne0inhk