当前位置: 首页 > news >正文

Redis热升级秘籍:零停机迁移方案与工具链

Redis热升级与零停机迁移完整方案

  • 第一章:热升级核心挑战与架构设计
    • 1.1 传统升级方式的局限性
    • 1.2 热升级架构设计原则
  • 第二章:核心迁移方案深度解析
    • 2.1 基于双写与增量同步的方案
    • 2.2 基于动态库热加载的方案
    • 2.3 云平台专业化方案
  • 第三章:完整工具链与实施流程
    • 3.1 工具链集成架构
    • 3.2 Redis-Shake高级配置
    • 3.3 全链路监控体系
  • 第四章:完整实施流程
    • 4.1 预迁移准备阶段
    • 4.2 迁移执行阶段
    • 4.3 回滚方案
  • 第五章:性能优化与最佳实践
    • 5.1 性能调优参数
    • 5.2 监控与告警最佳实践
  • 总结

第一章:热升级核心挑战与架构设计

1.1 传统升级方式的局限性

在分布式系统中,Redis作为关键的数据存储和缓存组件,其可用性直接关系到整个系统的稳定性。传统升级方式面临的根本性挑战:
数据一致性难题:

  • 停机窗口期内的数据丢失风险
  • 主从切换过程中的脑裂问题
  • 跨版本数据格式兼容性问题
    业务影响分析:
# 模拟传统停机升级的影响评估
#!/bin/bash
# upgrade_impact_assessment.shREDIS_QPS=50000  # 假设Redis集群峰值QPS
AVERAGE_REQUEST_VALUE=0.1 # 假设每个请求平均价值0.1元
DOWNTIME=300     # 计划停机时间5分钟# 计算业务损失
business_loss=$(echo "$REDIS_QPS * $AVERAGE_REQUEST_VALUE * $DOWNTIME" | bc)
echo "预计业务损失: $business_loss 元"# 计算影响用户数
ACTIVE_USERS=1000000 # 活跃用户数
affected_users=$(echo "$ACTIVE_USERS * $DOWNTIME / 86400" | bc)
echo "受影响用户数: $affected_users"

性能瓶颈分析:

  • 全量数据同步时的网络带宽占用
  • 持久化机制对I/O性能的影响
  • 同步过程中的内存压力

1.2 热升级架构设计原则

多层次高可用架构:

热升级系统架构
├── 流量控制层
│   ├── 智能代理 (Envoy/HAProxy)
│   ├── 流量调度器
│   └── 熔断机制
├── 数据同步层
│   ├── 全量同步引擎
│   ├── 增量同步引擎
│   └── 数据校验器
├── 状态管理层
│   ├── 元数据存储
│   ├── 状态机管理
│   └── 监控告警
└── 基础设施层├── 容器化部署├── 资源隔离└── 网络优化

设计原则:

  1. 零信任安全:所有通信必须加密,双向认证
  2. 最终一致性:确保数据最终一致,允许短暂延迟
  3. ** graceful degradation**:故障时优雅降级而非完全不可用
  4. 可观测性:全链路监控和追踪能力

第二章:核心迁移方案深度解析

2.1 基于双写与增量同步的方案

系统架构图:

Sync Layer
Target Cluster
Source Cluster
Proxy Layer
Client Layer
Redis-Shake
数据校验器
Redis主节点
Redis从节点
Redis主节点
Redis从节点
Envoy代理
客户端应用
客户端应用
客户端应用

Envoy双写配置详解:

# envoy-redis-dualwrite.yaml
admin:access_log_path: /tmp/admin_access.logaddress:socket_address: { address: 0.0.0.0, port: 9901 }static_resources:listeners:- name: redis_listeneraddress:socket_address: { address: 0.0.0.0, port: 6379 }filter_chains:- filters:- name: envoy.filters.network.redis_proxytyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.redis_proxy.v3.RedisProxystat_prefix: redis_statssettings:op_timeout: 5senable_redirection: trueenable_hashtagging: trueenable_command_stats: trueprefix_routes:catch_all_route:request_mirror_policy:cluster: new_redis_clusterruntime_fraction:  # 基于运行时的流量控制default_value:numerator: 100denominator: HUNDREDexclude_read_commands: true  # 排除读命令的双写cluster: old_redis_clusterclusters:- name: old_redis_clustertype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: old_redis_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address: { address: old-redis.example.com, port: 6379 }health_checks:- timeout: 1sinterval: 5sunhealthy_threshold: 3healthy_threshold: 1redis_health_check: {}- name: new_redis_clustertype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: new_redis_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address: { address: new-redis.example.com, port: 6379 }health_checks:- timeout: 1sinterval: 5sunhealthy_threshold: 3healthy_threshold: 1redis_health_check: {}

2.2 基于动态库热加载的方案

Redis内核改造实现:

// redis-hotupgrade.c
#include "server.h"
#include "dlfcn.h"// 全局函数指针,指向动态库中的实现
void (*libRedisCommand)(client *c);
void (*libProcessEvents)(void);
void (*libInitServer)(void);void *libHandle = NULL;// 加载新版本的动态库
int loadRedisLibrary(const char *libPath) {if (libHandle) {dlclose(libHandle);}libHandle = dlopen(libPath, RTLD_NOW | RTLD_DEEPBIND);if (!libHandle) {serverLog(LL_WARNING, "无法加载动态库: %s", dlerror());return C_ERR;}// 获取函数符号libRedisCommand = dlsym(libHandle, "redisCommand");libProcessEvents = dlsym(libHandle, "processEvents");libInitServer = dlsym(libHandle, "initServer");if (!libRedisCommand || !libProcessEvents || !libInitServer) {serverLog(LL_WARNING, "无法找到函数符号");dlclose(libHandle);return C_ERR;}serverLog(LL_NOTICE, "成功加载新版本动态库: %s", libPath);return C_OK;
}// 热升级命令处理
void upgradeCommand(client *c) {if (c->argc != 2) {addReplyError(c, "用法: UPGRADE <library_path>");return;}char *libPath = c->argv[1]->ptr;if (loadRedisLibrary(libPath) == C_OK) {addReplyStatus(c, "热升级成功");} else {addReplyError(c, "热升级失败");}
}// 在Redis初始化时注册命令
void registerUpgradeCommand(void) {struct redisCommand upgradeCmd = {"UPGRADE",upgradeCommand,2,"admin",0,NULL,0,0,0,0,0};redisRegisterCommand(&upgradeCmd);
}

编译和部署脚本:

#!/bin/bash
# build-redis-hotupgrade.sh# 编译主程序
gcc -o redis-server \-I./deps/hiredis -I./deps/linenoise -I./deps/lua/src \redis-hotupgrade.c \anet.c dict.c redis.c sds.c zmalloc.c \-ldl -lpthread -lm# 编译动态库版本
gcc -shared -fPIC -o redis-logic.so \-I./deps/hiredis -I./deps/linenoise -I./deps/lua/src \redis-logic.c anet.c dict.c sds.c zmalloc.c \-lpthread -lmecho "编译完成"
echo "启动命令: ./redis-server --hot-upgrade-enabled"
echo "升级命令: redis-cli UPGRADE ./redis-logic.so"

2.3 云平台专业化方案

Terraform自动化部署:

# redis-migration.tf
provider "aws" {region = "us-west-2"
}# 创建DMS复制实例
resource "aws_dms_replication_instance" "redis_migration" {replication_instance_id    = "redis-migration-instance"allocated_storage          = 100apply_immediately          = trueauto_minor_version_upgrade = trueavailability_zone          = "us-west-2a"engine_version            = "3.4.6"multi_az                  = falsepublicly_accessible       = falsereplication_instance_class = "dms.t3.medium"tags = {Name = "Redis Migration Instance"}
}# 配置源Redis端点
resource "aws_dms_endpoint" "source_redis" {endpoint_id   = "source-redis-endpoint"endpoint_type = "source"engine_name   = "redis"server_name   = var.source_redis_hostport          = 6379ssl_mode      = "require"username      = var.redis_usernamepassword      = var.redis_passwordredis_settings {auth_type          = "password"auth_user_name     = var.redis_usernameauth_password      = var.redis_passwordssl_security_protocol = "ssl-encryption"}
}# 配置目标Redis端点
resource "aws_dms_endpoint" "target_redis" {endpoint_id   = "target-redis-endpoint"endpoint_type = "target"engine_name   = "redis"server_name   = var.target_redis_hostport          = 6379ssl_mode      = "require"username      = var.redis_usernamepassword      = var.redis_passwordredis_settings {auth_type          = "password"auth_user_name     = var.redis_usernameauth_password      = var.redis_passwordssl_security_protocol = "ssl-encryption"}
}# 创建迁移任务
resource "aws_dms_replication_task" "redis_migration_task" {replication_task_id      = "redis-migration-task"migration_type           = "full-load-and-cdc"replication_instance_arn = aws_dms_replication_instance.redis_migration.replication_instance_arnsource_endpoint_arn      = aws_dms_endpoint.source_redis.endpoint_arntarget_endpoint_arn      = aws_dms_endpoint.target_redis.endpoint_arntable_mappings           = file("table-mappings.json")tags = {Name = "Redis Migration Task"}
}

第三章:完整工具链与实施流程

3.1 工具链集成架构

完整的迁移工具链:

迁移工具链生态系统
├── 数据同步工具
│   ├── redis-shake (阿里云)
│   ├── redis-migrate (Spotify)
│   └── redis-copier (自定义)
├── 数据校验工具
│   ├── redis-full-check
│   ├── redis-compare
│   └── custom-validator
├── 流量管理工具
│   ├── Envoy Redis Proxy
│   ├── HAProxy
│   └── Nginx Stream模块
├── 监控告警工具
│   ├── Prometheus exporter
│   ├── Grafana仪表板
│   └── 告警规则
├── 部署编排工具
│   ├── Ansible Playbooks
│   ├── Kubernetes Operators
│   └── Terraform模块
└── 自动化脚本├── 预检查脚本├── 迁移控制器└── 回滚管理器

3.2 Redis-Shake高级配置

生产环境配置模板:

{"type": "sync","source": {"address": "source-redis:6379","password": "${SOURCE_REDIS_PASSWORD}","tls": {"enable": true,"skip_verify": false,"ca_cert_path": "/certs/ca.crt","client_cert_path": "/certs/client.crt","client_key_path": "/certs/client.key"}},"target": {"address": "target-redis:6379","password": "${TARGET_REDIS_PASSWORD}","tls": {"enable": true,"skip_verify": false,"ca_cert_path": "/certs/ca.crt","client_cert_path": "/certs/client.crt","client_key_path": "/certs/client.key"}},"advanced": {"ncpu": 8,"parallel": 32,"batch_size": 512,"batch_count": 1024,"rate_limit": "100mb","wait_full": true,"resume_from_break_point": true,"break_point_file": "/data/breakpoint.json","filter": {"key_whitelist": ["important:*", "cache:*"],"key_blacklist": ["temp:*", "test:*"]}},"metrics": {"enable": true,"address": "0.0.0.0:9090","push_gateway": "prometheus:9091"}
}

启动和管理脚本:

#!/bin/bash
# redis-shake-manager.shCONFIG_FILE="/etc/redis-shake/config.json"
LOG_FILE="/var/log/redis-shake.log"
PID_FILE="/var/run/redis-shake.pid"start_migration() {echo "启动Redis数据迁移..."nohup ./redis-shake -config $CONFIG_FILE > $LOG_FILE 2>&1 &echo $! > $PID_FILEecho "迁移进程已启动,PID: $(cat $PID_FILE)"
}stop_migration() {if [ -f $PID_FILE ]; thenecho "停止迁移进程..."kill -TERM $(cat $PID_FILE)rm -f $PID_FILEecho "迁移已停止"elseecho "没有运行的迁移进程"fi
}monitor_progress() {tail -f $LOG_FILE | grep --line-buffered -E "progress|percentage|error" |while read line; doecho "[$(date '+%Y-%m-%d %H:%M:%S')] $line"# 这里可以添加告警逻辑if echo "$line" | grep -q "error"; thensend_alert "Redis迁移错误: $line"fidone
}check_consistency() {echo "开始数据一致性检查..."./redis-full-check \-s "source-redis:6379" \-p "$SOURCE_PASSWORD" \-t "target-redis:6379" \-a "$TARGET_PASSWORD" \--comparemode=3 \--logdir="/var/log/consistency" \--resultdir="/var/log/consistency"
}# 主控制循环
case "$1" instart)start_migration;;stop)stop_migration;;monitor)monitor_progress;;check)check_consistency;;*)echo "用法: $0 {start|stop|monitor|check}"exit 1;;
esac

3.3 全链路监控体系

Prometheus监控配置:

# prometheus-redis-migration.yml
global:scrape_interval: 15sevaluation_interval: 15sscrape_configs:- job_name: 'redis-migration'static_configs:- targets: ['redis-shake:9090']metrics_path: '/metrics'relabel_configs:- source_labels: [__address__]target_label: instance- source_labels: [__meta_redis_shake_role]target_label: role- job_name: 'redis-source'static_configs:- targets: ['source-redis:9121']metrics_path: '/metrics'params:target: ['source-redis:6379']relabel_configs:- source_labels: [__address__]target_label: instance- job_name: 'redis-target'static_configs:- targets: ['target-redis:9121']metrics_path: '/metrics'params:target: ['target-redis:6379']relabel_configs:- source_labels: [__address__]target_label: instance- job_name: 'envoy-proxy'static_configs:- targets: ['envoy:9901']metrics_path: '/stats/prometheus'alerting:alertmanagers:- static_configs:- targets: ['alertmanager:9093']rule_files:- /etc/prometheus/redis-migration-rules.yml

告警规则配置:

# redis-migration-rules.yml
groups:
- name: redis-migration-alertsrules:- alert: RedisMigrationLagTooHighexpr: redis_shake_incremental_sync_lag_seconds > 30for: 5mlabels:severity: warningannotations:summary: "Redis迁移延迟过高"description: "增量同步延迟已达到 {{ $value }} 秒"- alert: RedisMigrationErrorRateHighexpr: rate(redis_shake_error_total[5m]) > 0.1for: 2mlabels:severity: criticalannotations:summary: "Redis迁移错误率过高"description: "迁移错误率达到 {{ $value }} errors/second"- alert: SourceRedisMemoryHighexpr: redis_memory_used_bytes / redis_memory_max_bytes > 0.8for: 10mlabels:severity: warningannotations:summary: "源Redis内存使用率过高"description: "内存使用率达到 {{ $value }}%"- alert: TargetRedisConnectionsHighexpr: redis_connected_clients > 1000for: 5mlabels:severity: warningannotations:summary: "目标Redis连接数过高"description: "连接数达到 {{ $value }}"

第四章:完整实施流程

4.1 预迁移准备阶段

环境检查脚本:

#!/usr/bin/env python3
# pre_migration_check.pyimport redis
import sys
import json
from datetime import datetimedef check_redis_connection(host, port, password=None):"""检查Redis连接性"""try:client = redis.Redis(host=host, port=port, password=password, socket_timeout=5)client.ping()return True, "连接成功"except Exception as e:return False, f"连接失败: {str(e)}"def check_redis_version(host, port, password=None):"""检查Redis版本"""try:client = redis.Redis(host=host, port=port, password=password)info = client.info()return True, info['redis_version']except Exception as e:return False, f"获取版本失败: {str(e)}"def check_memory_usage(host, port, password=None):"""检查内存使用情况"""try:client = redis.Redis(host=host, port=port, password=password)info = client.info('memory')used_memory = int(info['used_memory'])max_memory = int(info['maxmemory']) if info['maxmemory'] != 0 else used_memoryusage_percent = (used_memory / max_memory) * 100 if max_memory > 0 else 0return True, {'used_memory': used_memory,'max_memory': max_memory,'usage_percent': usage_percent}except Exception as e:return False, f"获取内存信息失败: {str(e)}"def main():config = {'source': {'host': 'source-redis', 'port': 6379, 'password': 'source-pass'},'target': {'host': 'target-redis', 'port': 6379, 'password': 'target-pass'}}checks = []# 检查源集群checks.append(('源集群连接', check_redis_connection(**config['source'])))checks.append(('源集群版本', check_redis_version(**config['source'])))checks.append(('源集群内存', check_memory_usage(**config['source'])))# 检查目标集群checks.append(('目标集群连接', check_redis_connection(**config['target'])))checks.append(('目标集群版本', check_redis_version(**config['target'])))checks.append(('目标集群内存', check_memory_usage(**config['target'])))# 输出检查结果print("=" * 60)print("Redis迁移前置检查报告")print("=" * 60)print(f"检查时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")print("-" * 60)all_passed = Truefor check_name, (success, result) in checks:status = "✓" if success else "✗"print(f"{status} {check_name}: {result}")if not success:all_passed = Falseprint("-" * 60)if all_passed:print("✓ 所有检查通过,可以开始迁移")sys.exit(0)else:print("✗ 存在检查失败,请先解决问题")sys.exit(1)if __name__ == "__main__":main()

4.2 迁移执行阶段

分阶段迁移控制脚本:

#!/bin/bash
# migration-orchestrator.shset -e  # 遇到错误立即退出# 加载配置
source /etc/redis-migration/config.conf# 日志设置
LOG_FILE="/var/log/redis-migration.log"
exec > >(tee -a "$LOG_FILE") 2>&1# 阶段1: 环境准备
echo "阶段1: 环境准备"
./pre_migration_check.py
docker-compose up -d envoy
sleep 10# 阶段2: 全量数据同步
echo "阶段2: 全量数据同步"
./redis-shake -type sync -config /etc/redis-shake/full-sync.json &# 监控全量同步进度
while true; doprogress=$(curl -s http://redis-shake:9090/metrics | grep 'redis_shake_full_sync_percent' | awk '{print $2}')echo "全量同步进度: $progress%"if [ $(echo "$progress >= 100" | bc) -eq 1 ]; thenbreakfisleep 30
done# 阶段3: 增量同步和双写
echo "阶段3: 启用增量同步和双写"
./redis-shake -type increment -config /etc/redis-shake/increment-sync.json &# 更新Envoy配置启用双写
curl -X POST http://envoy:9901/update?enable_dualwrite=true# 阶段4: 数据校验
echo "阶段4: 数据校验"
./redis-full-check -s "$SOURCE_REDIS" -t "$TARGET_REDIS" \-p "$SOURCE_PASSWORD" -a "$TARGET_PASSWORD" \--comparemode=3 --logdir=/var/log/consistency# 阶段5: 流量切换
echo "阶段5: 流量切换"
curl -X POST http://envoy:9901/update?switch_to_target=true# 阶段6: 清理和验证
echo "阶段6: 清理和验证"
sleep 300  # 等待5分钟观察期
pkill redis-shake
docker-compose down envoyecho "迁移完成!"

4.3 回滚方案

自动化回滚脚本:

#!/usr/bin/env python3
# rollback-manager.pyimport redis
import requests
import time
import logging
from datetime import datetimelogging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')class RollbackManager:def __init__(self, source_host, target_host, envoy_host):self.source_client = redis.Redis(host=source_host, port=6379, decode_responses=True)self.target_client = redis.Redis(host=target_host, port=6379, decode_responses=True)self.envoy_host = envoy_hostdef check_data_divergence(self):"""检查数据差异"""logging.info("检查源和目标集群数据差异")# 采样检查关键数据sample_keys = self.source_client.randomkey(100)divergences = []for key in sample_keys:source_value = self.source_client.dump(key)target_value = self.target_client.dump(key)if source_value != target_value:divergences.append({'key': key,'source': source_value,'target': target_value})return divergencesdef trigger_rollback(self):"""触发回滚流程"""logging.info("开始回滚流程")# 1. 停止双写,切回源集群try:response = requests.post(f"http://{self.envoy_host}:9901/update",params={'switch_to_source': True})response.raise_for_status()logging.info("流量已切回源集群")except Exception as e:logging.error(f"切换流量失败: {e}")return False# 2. 等待稳定time.sleep(60)# 3. 验证业务恢复divergences = self.check_data_divergence()if divergences:logging.warning(f"发现 {len(divergences)} 个数据不一致项")# 这里可以添加数据修复逻辑logging.info("回滚完成")return Truedef automated_rollback_check(self):"""自动回滚检查"""# 监控关键指标,决定是否需要回滚metrics_to_check = ['target_redis_error_rate','target_redis_latency','target_redis_memory_usage']# 如果任何指标超过阈值,触发回滚if self.should_rollback():logging.warning("检测到异常,触发自动回滚")return self.trigger_rollback()return Falseif __name__ == "__main__":manager = RollbackManager(source_host="source-redis",target_host="target-redis",envoy_host="envoy")# 手动触发回滚import sysif len(sys.argv) > 1 and sys.argv[1] == "rollback":manager.trigger_rollback()

第五章:性能优化与最佳实践

5.1 性能调优参数

Redis-Shake性能优化:

{"advanced": {"ncpu": 16,"parallel": 64,"batch_size": 1024,"batch_count": 2048,"rate_limit": "500mb","wait_full": false,"resume_from_break_point": true,"break_point_file": "/data/breakpoint.json","filter": {"key_whitelist": ["important:*"],"key_blacklist": ["temp:*"]},"performance": {"compression": "snappy","buffer_size": "256mb","max_memory": "4gb","network_timeout": "30s","retry_interval": "5s","max_retries": 10}}
}

内核参数优化:

# /etc/sysctl.d/99-redis-migration.conf
# 网络栈优化
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1# 文件系统优化
vm.swappiness = 1
vm.overcommit_memory = 1
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5# 连接数优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

5.2 监控与告警最佳实践

Grafana监控看板配置:

{"dashboard": {"title": "Redis迁移监控看板","panels": [{"title": "数据同步吞吐量","type": "graph","targets": [{"expr": "rate(redis_shake_sync_bytes_total[5m])","legendFormat": "同步吞吐量"}],"yAxis": {"format": "bytes"}},{"title": "同步延迟","type": "graph","targets": [{"expr": "redis_shake_incremental_sync_lag_seconds","legendFormat": "同步延迟"}],"yAxis": {"format": "s"}},{"title": "错误率","type": "graph","targets": [{"expr": "rate(redis_shake_error_total[5m])","legendFormat": "错误率"}],"yAxis": {"format": "ops"}}],"time": {"from": "now-1h","to": "now"}}
}

总结

本方案详细介绍了Redis热升级与零停机迁移的完整解决方案,涵盖了架构设计、工具链集成、实施流程和性能优化等多个方面。通过采用基于Envoy双写和Redis-Shake同步的方案,可以实现真正的零停机迁移,确保业务连续性和数据一致性。
关键成功因素:

  1. 完善的准备工作:包括环境检查、资源评估和备份策略
  2. 合适的工具选择:根据具体场景选择最合适的迁移工具
  3. 全面的监控体系:实时监控迁移进度和系统状态
  4. 自动化操作流程:减少人工操作,提高可靠性和效率
  5. 完善的回滚方案:确保在出现问题时能够快速恢复
    通过遵循本方案的建议和实践,您可以成功实施Redis的热升级和迁移,确保系统的高可用性和数据的安全性。
http://www.dtcms.com/a/391228.html

相关文章:

  • 时序数据库选型指南深度解析IoTDB架构设计与性能对比
  • springboot超市管理系统的设计与实现(代码+数据库+LW)
  • 让Trae写一个AI的api中继服务
  • 跨国制造业SD-WAN:延迟下降78%,运维成本下降53%
  • MySQL服务启动不成功的可能解决方法
  • 硬解码出现画面回退分析
  • P1068 [NOIP 2009 普及组] 分数线划定-普及-
  • 用python语言如何排大小
  • pycharm连接GitHub,怎么配置 SSH 密钥并改用 SSH 连接
  • ​​[硬件电路-265]:电源系统要考虑的因素包括:不同的输出电压、隔离防干扰、防反、防浪涌、电压可调、电源开关、电池、可充电、低纹波、低噪声、防波动等
  • 【开题答辩全过程】以 基于Python的电影推荐系统为例,包含答辩的问题和答案
  • 格拉姆角场(Gramian Angular Field, GAF)详解
  • 前端开发工具Vue有哪些?常用Vue前端开发工具推荐、Vue开发工具对比与最佳实践分享
  • 基于vue的幼儿园健康管理系统0fz0y(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 第69课 分类任务: 基于BERT训练情感分类与区别二分类本质思考
  • Mysql杂志(二十)——MyISAM索引结构与B树B+树
  • Java 大视界 -- 基于 Java 的大数据实时流处理在金融高频交易数据分析中的应用
  • BonkFun 推出 USD1:Meme 币玩法的新入口
  • flutter在包含ListVIew的滚动列表页面中监听手势
  • Redis 三种集群模式详解
  • 打开hot100
  • Ant-Design Table中使用 AStatisticCountdown倒计时,鼠标在表格上移动时倒计时被重置
  • Linux crontab 定时任务工具使用
  • 阿里云RDS mysql8数据本地恢复,与本地主从同步(容器中)
  • 记录一次mysql启动失败问题解决
  • LeetCode算法练习:35.搜索插入位置
  • (1) 为什么推荐tauri框架
  • 嵌入式面试高频(八)!!!C++语言(嵌入式八股文,嵌入式面经)
  • Spring AI开发指导-工具调用
  • Linux 基本命令超详细解释第二期 | touch | cat | more | cp | mv | rm | which | find