Redis 高可用性:如何讓你的緩存一直在線,穩定運行?

🎯 引言:Redis的高可用性為啥這么重要?

在現代高可用系統中,Redis 是一款不可或缺的分布式緩存與數據庫系統。無論是提升訪問速度,還是實現數據的高效持久化,Redis 都能輕松搞定。可是,當你把 Redis 用于關鍵業務時,它的高可用性就顯得尤為重要。為了避免系統出現單點故障,保障業務連續性,我們需要有一套高可用架構來確保 Redis 的穩定運行。

今天,我們就一起來探討一下 Redis 高可用架構 的幾種實現方式,看看如何設計一套健壯的 Redis 高可用方案,保證我們的 Redis 緩存一直在線,穩定運行。


🛠? 1. Redis 主從復制:簡單的高可用方案

1.1 主從復制工作原理

Redis 主從復制(Master-Slave Replication)是 Redis 實現高可用性最基礎的方案之一。在這種架構中,你會有一個主節點(Master)和一個或多個從節點(Slave)。主節點負責處理寫操作和數據更新,而從節點則負責從主節點同步數據并進行只讀操作。

當主節點發生故障時,可以將某個從節點提升為主節點(手動或自動),確保系統的持續可用。

主從復制基本架構
  • 主節點(Master) :處理所有的寫操作(如SETDEL等命令)。
  • 從節點(Slave) :只處理讀操作(如GET命令),并定期從主節點同步數據。
    在這里插入圖片描述
主從復制工作流程
(1)初始同步

當從節點(Slave)首次啟動并連接到主節點時,它需要將主節點的數據完全同步過來。這個過程稱為“全量同步”。

  1. 從節點連接主節點:從節點向主節點發起連接請求。
  2. 主節點進行快照(RDB) :主節點執行 SAVEBGSAVE 命令,將當前的內存數據(RDB 快照)保存到磁盤。
  3. 從節點復制快照:主節點將保存的數據發送給從節點,從節點將數據寫入本地數據庫。
  4. 建立同步通道:從節點在完成全量同步后,開始監聽主節點的變更。
(2)增量同步

從節點已經有了主節點的數據快照后,接下來的數據同步就是增量同步,只同步主節點上的變更數據。

  1. 主節點記錄變更操作:主節點每處理一個寫操作(如SETDEL),會將這個操作寫入復制日志(replication log)中。
  2. 主節點發送變更命令給從節點:主節點將增量變更命令發送到所有的從節點。
  3. 從節點執行命令:從節點收到變更命令后,會在本地執行這些命令,保證數據的一致性。
(3)斷線恢復

如果從節點與主節點的連接丟失,Redis 會進行斷線恢復:

  • 當從節點重新連接到主節點時,Redis 會判斷是進行全量同步還是增量同步。如果從節點沒有數據快照,它會進行全量同步;如果有數據快照,則會通過增量同步方式進行恢復。
主從復制的特點
  • 只讀模式:從節點默認只能進行讀取操作(GET),不接受寫操作。寫操作必須通過主節點執行。
  • 延遲問題:由于從節點是從主節點獲取數據的,主節點的寫操作會有一定的延遲才會在從節點上看到。
  • 數據一致性:主從復制是最終一致性的,意味著從節點上的數據不會立即與主節點同步一致,在數據變更時可能會有短暫的不一致狀態。
主從復制的優勢
  • 提高可用性和可靠性:從節點可以用來分擔主節點的讀取壓力,還可以在主節點故障時迅速切換,保證服務的可用性。
  • 數據備份:從節點可以作為主節點的備份,提供數據冗余,防止主節點數據丟失。
  • 負載均衡:多個從節點可以分擔讀取請求,從而降低主節點的負載。
主從復制使用場景
  • 高可用架構:當主節點出現故障時,可以通過從節點提升一個新的主節點來實現故障切換。
  • 讀寫分離:主節點處理寫操作,從節點處理讀操作,優化性能。
  • 數據冗余:從節點可以作為數據的備份,一旦主節點出現問題,可以快速恢復數據。

1.2 主從復制搭建步驟

1、Redis 環境準備
  1. 下載安裝Redis

  2. 本次演示使用的版本是6.2.7版本(并且在本機環境模擬3個redis示例演示)

  3. 進行Redis目錄下創建 redis-cluster (mkdir redis-cluster)

  4. 復制原有redis.conf新建3個配置文件 redis-6379.conf redis-6380.conf redis-6381.conf
    在這里插入圖片描述

  5. 將配置文件放置到redis-cluster目錄下

  6. 編輯主節點(redis-6379.conf),主要修改以下配置項

    port 6379
    bind 127.0.0.1
    pidfile ./redis-cluster/redis-6379.pid
    logfile ./redis-cluster/redis-6379.log
    dir ./redis-cluster/data/redis-6379
    
  7. 編輯從節點(redis-6380.conf)

    port 6380
    bind 127.0.0.1
    pidfile ./redis-cluster/redis-6380.pid
    logfile ./redis-cluster/redis-6380.log
    dir ./redis-cluster/data/redis-6380
    replicaof 127.0.0.1 6379
    
  8. 編輯從節點(redis-6381.conf)

    port 6381
    bind 127.0.0.1
    pidfile ./redis-cluster/redis-6381.pid
    logfile ./redis-cluster/redis-6381.log
    dir ./redis-cluster/data/redis-6381
    replicaof 127.0.0.1 6379
    

配置完成,主要配置項說明:

  • port:每個 Redis 實例需要不同的端口。
  • pidfile:每個實例需要獨立的 PID 文件。
  • logfile:每個實例需要不同的日志文件。
  • replicaof:設置主從復制指定主節點。
  • dir:設置數據文件的存儲路徑。確保每個 Redis 實例的 dir 路徑存在(提前創建,用于存儲數據文件)

每個實例都需要不同的配置(特別是端口、PID 文件、日志文件和數據目錄),確保它們不會沖突。

2、啟動 Redis 實例
  1. 打開 命令終端

  2. 進入 Redis 所在的目錄

  3. 啟動3個實例

    ./src/redis-server ./redis-cluster/redis-6379.conf
    ./src/redis-server ./redis-cluster/redis-6380.conf
    ./src/redis-server ./redis-cluster/redis-6381.conf
    
  4. 檢查實例是否正常
    你可以通過 redis cli 連接到每個實例,確認它們是否成功啟動。

  5. 檢查主從復制是否正常或者連接到主節點新增鍵值看同步是否成功

    ./src/redis-cli -p 6379 info replication
    ./src/redis-cli -p 6380 info replication
    

    主節點在這里插入圖片描述

    從節點
    在這里插入圖片描述

    說明主從復制成功。

?? 2. Redis Sentinel:自動故障轉移的英雄

2.1 Redis Sentinel的工作原理

Redis Sentinel 是 Redis 提供的自動故障轉移系統。它監控 Redis 實例的健康狀況,一旦主節點發生故障,Sentinel 會自動將一個從節點提升為主節點,并更新所有從節點的信息,保證系統的高可用性。Sentinel 的作用不止于監控故障,它還可以提供自動故障轉移、配置發布以及客戶端連接的重定向。

哨兵部署架構

在這里插入圖片描述

1、監控:Sentinel 會不斷檢查 master 和 slave 是否按預期工作。
2、自動故障恢復:如果 master 故障,Sentinel 會將一個 slave 提升為 master,當故障實例恢復后也會安裝新的 master 為主節點。
3、通知:Sentinel 充當 Redis 客戶端的服務發現來源,當集群發生故障轉移時,會將最新節點信息推送給 Redis 客戶端。

哨兵集群監控原理

Sentinel 基于心跳機制監測服務狀態,每隔1秒向集群的每個實例發送ping命令:

  • 主觀下線:如果某 Sentinel 節點發現某實例未在規定時間響應,則認為該實例主觀下線。
  • 客觀下線:若超過指定數量(quorum)的 Sentinel 都認為該實例主觀下線,則該實例客觀下線。quorum 值最好超過 Sentinel 實例數量的一半。

在這里插入圖片描述

集群故障恢復原理

一旦發現 master 故障,Sentinel 需要在 salve 中選擇一個作為新的 master,選擇依據是這樣的:

  • 首先會判斷 slave 節點與 master 節點斷開時間長短 ,如果超過指定值(downafter-milliseconds * 10)則會排除該 slave 節點
  • 然后判斷 slave 節點的 slave-priority 值,越小優先級越高,如果是0則永不參與選舉
  • 如果slave-priority一樣,則判斷 slave 節點的 offset 值 ,越大說明數據越新,優先級越高
  • 最后是判斷slave節點的 運行id 大小,越小優先級越高。

當選出一個新的 master 之后,該如何實現切換呢?
流程如下:

  • Sentinel給備選的 slave1 節點發送 slaveof no one 命令,讓該節點成為 master
  • Sentinel給所有其它 slave 發送 slaveof 127.0.0.1 6380 命令,讓這些 slave 成為新 master 的從節點,開始從新的 master 上同步數據。
  • 最后,Sentinel 將故障節點標記為 slave,當故障節點恢復后會自動成為新的 master 的 slave 節點。
    在這里插入圖片描述

2.2 配置 Redis Sentinel(哨兵)

部署多個 Redis 實例后,配置 Redis Sentinel 以實現高可用性,可以通過以下步驟來完成。哨兵模式的主要功能是監控 Redis 主節點和從節點的狀態,并在主節點宕機時自動切換到從節點。

  • 你已經有了多個 Redis 實例(例如637963806381)。
  • 你希望配置 Sentinel 來監控這些實例,并在主節點宕機時進行自動故障轉移。

每個 Redis 哨兵都需要配置一個 sentinel.conf 文件來監控主節點。你可以創建多個 Sentinel 配置文件,并通過它們來監控 Redis 實例。

設置哨兵配置文件(sentinel.conf) 內容如下:

port 26379
bind 127.0.0.1
pidfile "./redis-cluster/sentinel-26379/sentinel-26379.pid"
logfile "./redis-cluster/sentinel-26379/sentinel-26379.log"
dir "./redis-cluster/sentinel-26379"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

復制文件進行 26380 和 26381 哨兵的配置。

port 26380
bind 127.0.0.1
pidfile "./redis-cluster/sentinel-26380/sentinel-26380.pid"
logfile "./redis-cluster/sentinel-26380/sentinel-26380.log"
dir "./redis-cluster/sentinel-26380"
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
  • sentinel monitor mymaster:這是 Sentinel 監控的主節點名稱,這里設置為 mymaster,并且指定了主節點的 IP 和端口(127.0.0.1 6379)。后面的數字 2 表示至少需要 2 個哨兵節點確認主節點宕機后,才會進行故障轉移。
  • sentinel down-after-milliseconds mymaster 5000:當主節點 5 秒沒有響應時,認為該節點宕機。
  • sentinel failover-timeout mymaster 10000:故障轉移的超時時間。
  • sentinel parallel-syncs mymaster 1:指定故障轉移時,最多有多少個從節點同步數據。

2.3 啟動 Redis Sentinel(哨兵)

  1. 你可以啟動多個 Sentinel 實例來提高容錯性。

    ./src/redis-sentinel ./redis-cluster/sentinel-26379.conf
    ./src/redis-sentinel ./redis-cluster/sentinel-26380.conf
    ./src/redis-sentinel ./redis-cluster/sentinel-26381.conf
    
  2. 驗證哨兵狀態查看是否發現主節點

    ./src/redis-cli -p 26379 sentinel masters
    

    在這里插入圖片描述

  3. 查看從節點狀態

    ./src/redis-cli -p 26379 sentinel slaves mymaster
    

    在這里插入圖片描述5. 搭建完成,這說明 Sentinel 已經自動發現并管理了從節點 🎯

2.4 哨兵模式連接Redis

在Sentinel集群監管下的Redis主從集群,其節點會因為自動故障轉移而發生變化,Redis的客戶端必須感知這種變化,及時更新連接信息。
客戶端應用程序應該使用RedisSentinel模式連接Redis,而不是直接固定的Redis的IP。我們可以直接通過哨兵獲取到當前的主節點IP。可以使用命令:

./src/redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

在這里插入圖片描述

我們通過一個測試來實現Spring Boot實現集成哨兵機制。

Maven依賴

        <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.15.3</version></dependency>

配置文件添加配置項

spring:redis:sentinel:master: mymasternodes: 127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381host: 127.0.0.1port: 6379database: 1 # 默認使用 0 庫password:

測試連接代碼

@Configuration
@AutoConfigureBefore({RedisAutoConfiguration.class, RedissonAutoConfiguration.class})
public class RedissonConfig {protected final Logger logger = LoggerFactory.getLogger(this.getClass());@Value("${spring.redis.host}")private String host;@Value("${spring.redis.port}")private String port;@Value("${spring.redis.password}")private String password;@Value("${spring.redis.database}")private int database;@Value("${spring.redis.sentinel.master}")private String sentinelMaster;@Value("${spring.redis.sentinel.nodes}")private String sentinelNodes;@Value("${redisson.threads:4}")private int threads;@Value("${redisson.nettyThreads:5}")private int nettyThreads;@Value("${redisson.connectPoolSize:20}")private int connectPoolSize;@Value("${redisson.connectPoolIdleSize:5}")private int connectPoolIdleSize;@Value("${redisson.connectTimeout:10000}")private int connectTimeout;@Value("${redisson.retryAttempts:3}")private int retryAttempts;@Value("${redisson.retryInterval:1500}")private int retryInterval;@Value("${redisson.timeout:10000}")private int timeout;@Value("${redisson.pingConnectionInterval:30000}")private int pingConnectionInterval;@Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean(RedissonClient.class)public RedissonClient redisson() throws IOException {Config config = new Config();int cpuCores = Runtime.getRuntime().availableProcessors();threads = (threads == 0 ? cpuCores * 2 : threads);nettyThreads = (nettyThreads == 0 ? cpuCores : nettyThreads);config.setThreads(threads);config.setNettyThreads(nettyThreads);config.setTransportMode(TransportMode.NIO);// 設置序列化(禁用class類型信息)config.setCodec(new SimpleRedisJsonCodec());if (StringUtils.isNotEmpty(sentinelMaster) && StringUtils.isNotEmpty(sentinelNodes)) {// 支持哨兵模式logger.info("RedissonClient init useSentinelServers");String[] sentinels = sentinelNodes.split(",");config.useSentinelServers().setMasterName(sentinelMaster).setDatabase(database).setPassword(StringUtils.isEmpty(password) ? null : password).setTimeout(timeout).addSentinelAddress(formatRedisUrls(sentinels));} else if (host.contains(",")) {// 集群模式logger.info("RedissonClient init useClusterServers");String[] clusterNodes = host.split(",");ClusterServersConfig cConfig = config.useClusterServers();for (String node : clusterNodes) {cConfig.addNodeAddress("redis://" + node + ":" + port);}cConfig.setPassword(password);cConfig.setMasterConnectionPoolSize(connectPoolSize);cConfig.setMasterConnectionMinimumIdleSize(connectPoolIdleSize);cConfig.setConnectTimeout(connectTimeout);cConfig.setRetryAttempts(retryAttempts);cConfig.setRetryInterval(retryInterval);cConfig.setTimeout(timeout);cConfig.setPingConnectionInterval(pingConnectionInterval);} else {// 單機模式logger.info("RedissonClient init useSingleServer");config.useSingleServer().setAddress("redis://" + host + ":" + port).setDatabase(database).setPassword(StringUtils.isEmpty(password) ? null : password).setConnectionPoolSize(connectPoolSize).setConnectionMinimumIdleSize(connectPoolIdleSize).setTimeout(timeout);}return Redisson.create(config);}/*** 格式化 Redis URL,確保前綴一致*/private String[] formatRedisUrls(String[] nodes) {return Arrays.stream(nodes).map(node -> node.startsWith("redis://") ? node : "redis://" + node).toArray(String[]::new);}
}

連接成功
在這里插入圖片描述

2.5 測試故障轉移

你可以通過停掉主節點(6379)來測試故障轉移的功能。停掉主節點后,Sentinel 會自動將從節點提升為新的主節點。

  1. 停止主節點(6379

  2. Sentinel 會檢測到主節點宕機,并自動執行故障轉移,將選擇一個從節點升級為新的主節點。你可以通過以下命令查看新的 Sentinel 的主節點。可以看到新的主節點已經變成6381。

	./src/redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster1) "127.0.0.1"2) "6381"

并且SpringBoot中自動感知到節點變化,業務可正常使用,不受到Redis節點宕掉的影響。
在這里插入圖片描述

  • 自動化:Sentinel 自動監控 Redis 狀態,發生故障時,自動完成故障轉移。
  • 高可用:Redis Sentinel 可以防止單點故障,增強系統的穩定性。

? 3. Redis Cluster:實現水平擴展和高可用性的終極武器

3.1 Redis Cluster的工作原理

Redis Cluster 是 Redis 3.0 引入的一個新特性,它可以實現水平擴展并且在多個節點之間分配數據。Redis Cluster 是基于分片的架構,數據會自動分布到不同的節點上。每個節點都有一個主節點和若干從節點組成的高可用集群。

當某個節點發生故障時,Redis Cluster 可以自動將從節點提升為主節點,繼續保持服務的可用性。同時,Cluster 支持 自動分片,即每個節點負責一部分數據。

3.2 Redis Cluster的搭建步驟

持續更新中…

🚀 4. 實際應用案例:如何實現生產環境中的 Redis 高可用架構

在實際生產環境中,Redis 的高可用架構設計需要根據具體的需求來選擇適合的方案。比如,對于需要高吞吐量和低延遲的場景,使用 Redis Cluster 是一個不錯的選擇;而對于一些中小型應用,可以選擇 Redis Sentinel 來確保故障自動切換。

4.1 使用 Redis Sentinel 實現高可用

  1. 部署 Redis 實例:設置主從節點,并在至少 3 個機器上運行 Redis。
  2. 配置 Sentinel:配置 Sentinel 進行監控和故障轉移。
  3. 自動切換:當主節點宕機時,Sentinel 自動將從節點提升為主節點。

4.2 使用 Redis Cluster 實現高可用

  1. 分配數據分片:將數據分配到多個 Redis 節點上,每個節點負責不同的數據分片。
  2. 設置集群:通過 redis-trib 工具來創建 Redis 集群。
  3. 監控集群狀態:使用 redis-cli 檢查集群狀態,確保節點間通信正常。

🔒 5. 結論:如何選擇合適的 Redis 高可用方案?

每個系統對 Redis 高可用性的需求都不盡相同,因此選擇合適的架構尤為重要:

  • 小型系統:可以選擇 Redis 主從復制,設置少量的從節點來提升讀取性能。
  • 中型系統:使用 Redis Sentinel 來實現自動故障轉移,并增加更多的監控和故障處理功能。
  • 大型系統:對于大規模的應用,建議使用 Redis Cluster 進行分片存儲與水平擴展,并結合 Sentinel 進行高可用性保障。

通過了解 Redis 的高可用架構,結合實際業務需求來進行部署,我們就能避免系統因為 Redis 故障導致的業務中斷,提升整體系統的可靠性。


? 總結:Redis 緩存一直在線,穩定運行

Redis 的高可用性不僅關乎緩存系統的穩定性,更是支撐業務連續性的關鍵。通過選擇合適的高可用架構,我們可以讓 Redis 在系統故障時仍然堅挺不倒,保證業務流暢運行。

希望你通過這篇文章了解了 Redis 主從復制、Sentinel 和 Cluster 的不同高可用實現方式,找到適合自己的方案,確保 Redis 在高負載下仍能保持穩定運行!

🌟 你的支持是我持續創作的動力,歡迎點贊、收藏、分享!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71158.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71158.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71158.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面試題:說一下你對DDD的了解?

面試題:說一下你對DDD的了解? 在面試中,關于 DDD(領域驅動設計,Domain-Driven Design) 的問題是一個常見的技術考察點。DDD 是一種軟件設計方法論,旨在通過深入理解業務領域來構建復雜的軟件系統。以下是一個清晰、詳細的回答模板,幫助你在面試中脫穎而出: DDD 的定義…

Redis---緩存穿透,雪崩,擊穿

文章目錄 緩存穿透什么是緩存穿透&#xff1f;緩存穿透情況的處理流程是怎樣的&#xff1f;緩存穿透的解決辦法緩存無效 key布隆過濾器 緩存雪崩什么是緩存雪崩&#xff1f;緩存雪崩的解決辦法 緩存擊穿什么是緩存擊穿&#xff1f;緩存擊穿的解決辦法 區別對比 在如今的開發中&…

Android Logcat 高效調試指南

工具概覽 Logcat 是 Android SDK 提供的命令行日志工具&#xff0c;支持靈活過濾、格式定制和實時監控&#xff0c;官方文檔詳見 Android Developer。 基礎用法 命令格式 [adb] logcat [<option>] ... [<filter-spec>] ... 執行方式 直接調用&#xff08;通過ADB守…

【定昌Linux系統】部署了java程序,設置開啟啟動

將代碼上傳到相應的目錄&#xff0c;并且配置了一個.sh的啟動腳本文件 文件內容&#xff1a; #!/bin/bash# 指定JAR文件的路徑&#xff08;如果JAR文件在當前目錄&#xff0c;可以直接使用文件名&#xff09; JAR_FILE"/usr/local/java/xs_luruan_client/lib/xs_luruan_…

Java 8 中,可以使用 Stream API 和 Comparator 對 List 按照元素對象的時間字段進行倒序排序

文章目錄 引言I 示例對象II List 按時間字段倒序排序: 使用 `Stream` 和 `Comparator` 排序方法 1:使用 `Comparator.comparing`方法 2:使用 `Comparator.reversed`方法 3:自定義 `Comparator`輸出結果III 注意事項**時間字段類型**:**空值處理**:IV 總結引言 案例:在線用…

jvm內存模型,類加載機制,GC算法,垃圾回收器,jvm線上調優等常見的面試題及答案

JVM內存模型 JVM內存模型包括哪些區域 答案&#xff1a;JVM內存模型主要包括以下區域&#xff1a; 程序計數器&#xff1a;是一塊較小的內存空間&#xff0c;它可以看作是當前線程所執行的字節碼的行號指示器&#xff0c;用于記錄正在執行的虛擬機字節碼指令的地址。Java虛擬機…

git clone的時候出現出現error

報錯如下&#xff1a; Collecting githttps://github.com/haotian-liu/LLaVA.git Cloning https://github.com/haotian-liu/LLaVA.git to /tmp/pip-req-build-360q6tt1 Running command git clone --filterblob:none --quiet https://github.com/haotian-liu/LLaVA.git /t…

Minio搭建并在SpringBoot中使用完成用戶頭像的上傳

Minio使用搭建并上傳用戶頭像到服務器操作,學習筆記 Minio介紹 minio官網 MinIO是一個開源的分布式對象存儲服務器&#xff0c;支持S3協議并且可以在多節點上實現數據的高可用和容錯。它采用Go語言開發&#xff0c;擁有輕量級、高性能、易部署等特點&#xff0c;并且可以自由…

vue3中ref和reactive響應式數據、ref模板引用(組合式和選項式區別)、組件ref的使用

目錄 Ⅰ.ref 1.基本用法&#xff1a;ref響應式數據 2.ref模板引用 3.ref在v-for中的模板引用 ?4.ref在組件上使用 ?5.TS中ref數據標注類型 Ⅱ.reactive 1.基本用法&#xff1a;reactive響應式數據 2.TS中reactive標注類型 Ⅲ.ref和reactive的使用場景和區別 Ⅳ.小結…

javascript實現雪花飄落效果

本文實現雪花飄落效果的 JavaScript 網頁設計案例&#xff0c;代碼實現如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, init…

項目準備(flask+pyhon+MachineLearning)- 3

目錄 1.商品信息 2. 商品銷售預測 2.1 機器學習 2.2 預測功能 3. 模型評估 1.商品信息 app.route(/products) def products():"""商品分析頁面"""data load_data()# 計算當前期間和上期間current_period data[data[成交時間] > data[成…

FPGA開發,使用Deepseek V3還是R1(3):系統級與RTL級

以下都是Deepseek生成的答案 FPGA開發&#xff0c;使用Deepseek V3還是R1&#xff08;1&#xff09;&#xff1a;應用場景 FPGA開發&#xff0c;使用Deepseek V3還是R1&#xff08;2&#xff09;&#xff1a;V3和R1的區別 FPGA開發&#xff0c;使用Deepseek V3還是R1&#x…

實現 Leaflet 多類型點位標記與聚合功能的實戰經驗分享

在現代的地理信息系統&#xff08;GIS&#xff09;應用中&#xff0c;地圖功能是不可或缺的一部分。無論是展示商業網點、旅游景點還是公共服務設施&#xff0c;地圖都能以直觀的方式呈現數據。然而&#xff0c;當數據量較大時&#xff0c;地圖上可能會出現大量的標記點&#x…

企微審批中MySQL字段TEXT類型被截斷的排查與修復實踐

在MySQL中&#xff0c;TEXT類型字段常用于存儲較大的文本數據&#xff0c;但在一些應用場景中&#xff0c;當文本內容較大時&#xff0c;TEXT類型字段可能無法滿足需求&#xff0c;導致數據截斷或插入失敗。為了避免這種問題&#xff0c;了解不同文本類型&#xff08;如TEXT、M…

【常見BUG】Spring Boot 和 Springfox(Swagger)版本兼容問題

???歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學習,不斷總結,共同進步,活到老學到老…

HTTP 協議的發展歷程:從 HTTP/1.0 到 HTTP/2.0

HTTP 協議的發展歷程&#xff1a;從 HTTP/1.0 到 HTTP/2.0 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是 Web 的基礎協議&#xff0c;用于客戶端和服務器之間的通信。從 HTTP/1.0 到 HTTP/2.0&#xff0c;HTTP 協議經歷了多次重大改…

apload-lab打靶場

1.提示顯示所以關閉js 上傳<?php phpinfo(); ?>的png形式 抓包&#xff0c;將png改為php 然后放包上傳成功 2.提示說檢查數據類型 抓包 將數據類型改成 image/jpeg 上傳成功 3.提示 可以用phtml&#xff0c;php5&#xff0c;php3 4.先上傳.htaccess文件&#xff0…

金融支付行業技術側重點

1. 合規問題 第三方支付系統的平穩運營&#xff0c;嚴格遵循《非銀行支付機構監督管理條例》的各項條款是基礎與前提&#xff0c;其中第十八條的規定堪稱重中之重&#xff0c;是支付機構必須牢牢把握的關鍵準則。 第十八條明確指出&#xff0c;非銀行支付機構需構建起必要且獨…

Cherry Studio + 火山引擎 構建個人AI智能知識庫

&#x1f349;在信息化時代&#xff0c;個人知識庫的構建對于提高工作效率、知識管理和信息提取尤為重要。尤其是當這些知識庫能結合人工智能來智能化地整理、分類和管理數據時&#xff0c;效果更為顯著。我最近嘗試通過 Cherry Studio 和 火山引擎 來搭建個人智能知識庫&#…

LeetCode 2 - 兩數相加

LeetCode 2 - 兩數相加 是一道經典鏈表操作問題&#xff0c;經常作為面試中基礎題的變體被考察。掌握多種解法及其變體&#xff0c;并熟悉其核心思路和模板代碼&#xff0c;可以快速備戰相關鏈表或大數計算問題。 題目描述 給定兩個非空鏈表&#xff0c;它們代表兩個非負整數&…