分布式ID與冪等性面試題整理

分布式ID與冪等性面試題整理

文章目錄

  • 分布式ID與冪等性面試題整理
    • 一、分布式ID
      • 1. 為什么需要分布式ID?
      • 2. 分布式ID的核心要求
      • 3. 常見分布式ID方案
        • (1) UUID
        • (2) 數據庫自增
        • (3) Redis自增
        • (4) 雪花算法(Snowflake)
        • (5) 美團Leaf/百度UidGenerator
      • 4. 雪花算法詳解
    • 二、冪等性
      • 1. 什么是冪等性?
      • 2. 為什么需要冪等性?
      • 3. 實現冪等性的常見方案
        • (1) 唯一索引
        • (2) 樂觀鎖
        • (3) 狀態機
        • (4) Token機制
        • (5) 去重表
        • (6) 全局ID
      • 4. 不同場景的冪等實踐
        • HTTP接口冪等
        • 消息隊列冪等
        • 定時任務冪等
      • 5. 冪等性與并發控制
    • 三、綜合實戰
      • 1. 設計一個分布式ID生成服務
      • 2. 支付系統的冪等設計
      • 3. 分布式事務與冪等

一、分布式ID

1. 為什么需要分布式ID?

問題:在分布式系統中,為什么不能直接使用數據庫自增ID?

答案

  • 單點故障:自增ID依賴單數據庫,數據庫掛了整個系統就癱瘓
  • 性能瓶頸:所有ID生成請求都打到同一個數據庫,壓力大
  • 擴展困難:分庫分表時,自增ID會導致重復或需要復雜協調
  • 安全問題:連續的數字ID容易暴露業務量,可能被爬取數據

2. 分布式ID的核心要求

問題:一個好的分布式ID生成方案需要滿足哪些要求?

答案

  1. 全局唯一:整個系統內絕對不能重復
  2. 趨勢遞增:最好是有序的,方便數據庫索引
  3. 高可用:ID生成服務不能成為單點故障
  4. 高性能:每秒至少能生成幾萬ID
  5. 安全:不能暴露業務信息(如訂單量)

3. 常見分布式ID方案

問題:常見的分布式ID生成方案有哪些?各自原理是什么?

答案

(1) UUID
  • 原理:隨機生成128位數字,格式如550e8400-e29b-41d4-a716-446655440000
  • 優點:簡單,本地生成無網絡開銷
  • 缺點:無序導致索引性能差,字符串存儲空間大
(2) 數據庫自增
  • 原理:單獨數據庫表,通過REPLACE INTO或事務獲取ID
  • 優點:實現簡單,ID有序
  • 缺點:數據庫單點風險,性能有限
(3) Redis自增
  • 原理:利用Redis的INCR命令生成ID
  • 優點:性能比數據庫好
  • 缺點:需維護Redis集群,持久化問題可能導致ID重復
(4) 雪花算法(Snowflake)
  • 原理:64位ID = 1位符號位(0) + 41位時間戳 + 10位機器ID + 12位序列號
  • 優點:本地生成性能高,ID有序
  • 缺點:依賴機器時鐘,時鐘回撥會導致ID重復
(5) 美團Leaf/百度UidGenerator
  • 原理:改進版雪花算法,解決時鐘回撥問題,引入ZK協調
  • 優點:解決了原生雪花算法的問題
  • 缺點:系統復雜度高

4. 雪花算法詳解

問題:詳細解釋雪花算法的實現原理?

答案

0 | 0001100 10100010 10111110 10001001 01011100 | 00 | 00001 | 000000000000
  • 第1位:符號位,始終為0
  • 中間41位:毫秒級時間戳,可用69年
  • 接著10位:5位數據中心ID + 5位機器ID(最多1024個節點)
  • 最后12位:序列號,每毫秒可生成4096個ID

時鐘回撥問題處理

  1. 輕微回撥:等待時間追上
  2. 嚴重回撥:報警人工介入
  3. 美團Leaf方案:使用ZK記錄最大時間戳

二、冪等性

1. 什么是冪等性?

問題:用通俗語言解釋什么是冪等性?

答案

  • 通俗理解:同樣的操作執行一次和執行N次,效果一樣
  • 舉例:
    • 支付:同一筆訂單只扣一次錢
    • 短信:同一條通知只發一次
    • 狀態更新:最終狀態一致

2. 為什么需要冪等性?

問題:分布式系統中為什么特別關注冪等性?

答案

  • 網絡問題:請求超時可能導致客戶端重試
  • 微服務調用:服務調用失敗會觸發重試機制
  • 消息隊列:消息可能被重復消費
  • 用戶行為:用戶可能多次點擊提交按鈕

3. 實現冪等性的常見方案

問題:有哪些實現冪等性的方案?各自適用場景?

答案

(1) 唯一索引
  • 原理:數據庫唯一索引防止重復數據
  • 場景:創建訂單等插入操作
  • 實現:訂單ID、業務編號等加唯一索引
(2) 樂觀鎖
  • 原理:通過版本號控制更新

  • 場景:更新操作如賬戶余額變更

  • 實現:

    UPDATE account SET balance=balance-100, version=version+1 
    WHERE id=123 AND version=5
    
(3) 狀態機
  • 原理:業務狀態流轉控制

  • 場景:訂單狀態等有明確流轉的業務

  • 實現:

    UPDATE order SET status='paid' WHERE id=456 AND status='unpaid'
    
(4) Token機制
  • 原理:客戶端先獲取令牌,服務端校驗后刪除
  • 場景:防止表單重復提交
  • 實現:
    1. 服務端生成token存入Redis
    2. 提交時攜帶token
    3. 校驗后刪除token
(5) 去重表
  • 原理:記錄已處理請求ID

  • 場景:消息隊列消費等

  • 實現:

    INSERT INTO request_log(request_id, biz_type) VALUES('req123', 'order')
    -- 先查是否存在再處理
    
(6) 全局ID
  • 原理:利用分布式ID的唯一性
  • 場景:所有需要冪等的場景
  • 實現:結合雪花算法等生成唯一業務ID

4. 不同場景的冪等實踐

問題:針對以下場景如何保證冪等性?

  1. HTTP接口
  2. 消息隊列消費
  3. 定時任務

答案

HTTP接口冪等
  1. GET:天然冪等
  2. POST:
    • 前端:提交按鈕禁用+loading
    • 后端:Token機制+唯一索引
  3. PUT/DELETE:天然冪等(需正確實現)
消息隊列冪等
  1. RabbitMQ:
    • 消息唯一ID+去重表
    • 手動ack確保處理完成
  2. Kafka:
    • 利用offset控制
    • 消費者組+分區保證順序
定時任務冪等
  1. 加鎖:分布式鎖(Redis/ZK)
  2. 狀態檢查:記錄上次執行結果
  3. 時間窗口:允許短時間重復但結果一致

5. 冪等性與并發控制

問題:冪等性和并發控制有什么區別?

答案

  • 冪等性:關注多次操作的結果一致性
  • 并發控制:關注同時操作的順序和正確性
  • 聯系:
    • 都需要唯一標識
    • 都可能導致數據不一致
  • 區別:
    • 冪等解決重復問題
    • 并發控制解決競爭問題

三、綜合實戰

1. 設計一個分布式ID生成服務

問題:如何設計一個類似美團Leaf的分布式ID服務?

答案

架構設計

  1. 服務層:無狀態服務,可水平擴展
  2. 存儲層:
    • ZK:協調worker節點分配
    • Redis:緩存號段,提高性能
  3. ID生成:
    • 號段模式:每次獲取一批ID(如1-1000)
    • 雙Buffer:一個用完前預加載下一個

核心流程

  1. 啟動時向ZK注冊獲取workerID
  2. 從DB獲取號段范圍(UPDATE max_id=max_id+step)
  3. 內存中分配ID,快用完時異步加載下一號段
  4. 定期持久化當前分配位置

2. 支付系統的冪等設計

問題:支付系統如何防止重復扣款?

答案

全鏈路設計

  1. 訂單創建

    • 訂單ID使用雪花算法
    • 訂單表order_id唯一索引
  2. 支付請求

    • 前端:支付按鈕防重
    • 生成支付流水號(支付系統唯一)
  3. 支付核心

    // 偽代碼
    public Result pay(String orderId, BigDecimal amount) {// 1. 檢查訂單狀態Order order = orderDao.get(orderId);if (order.isPaid()) {return Result.success("已支付");}// 2. 樂觀鎖更新int updated = orderDao.updateStatus(orderId, "unpaid", "paying");if (updated == 0) {return Result.fail("并發操作");}// 3. 實際扣款boolean success = accountService.debit(order.getUserId(), amount);// 4. 最終狀態if (success) {orderDao.updateStatus(orderId, "paying", "paid");} else {orderDao.updateStatus(orderId, "paying", "failed");}
    }
    
  4. 對賬補救:定時核對訂單與支付記錄

3. 分布式事務與冪等

問題:分布式事務場景下如何保證冪等性?

答案

結合方案

  1. TCC模式
    • Try階段:生成事務ID,記錄預備狀態
    • Confirm/Cancel:通過事務ID保證冪等
  2. 本地消息表
    • 業務與消息表在同一個事務
    • 消息ID作為去重依據
  3. Saga模式
    • 每個步驟有補償操作
    • 通過業務ID保證補償冪等

關鍵點

  • 事務ID全局唯一
  • 操作前檢查狀態
  • 補償操作也要冪等

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

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

相關文章

node.js學習筆記1

目錄 Node.js是什么 Node.js下載與安裝 Buffer緩沖區 一些計算機硬件基礎 程序運行的基本流程 Node.js是什么 node.js是一個JavaScript運行環境,或者說,node.js是一個可以運行JavaScript的軟件。 可以用于開發服務端、桌面端、工具類應用。 服務器…

游戲開發日志

我來為您逐行詳細講解這個 ViewMgr.cs 文件。這是一個Unity游戲中的視野管理系統,用于優化游戲性能。## 文件結構概覽這個文件主要包含以下幾個部分: 1. 數據結構和接口定義 2. 視野管理器 ViewMgr 類 3. 工具類 ViewTools讓我逐行為您講解:#…

使用 PlanetScope 衛星圖像繪制水質參數:以莫干湖為例

1.數據采集 我使用ArcGIS Pro 中的Planet Imagery插件下載了 2023 年 6 月 25 日的安卡拉莫干湖衛星圖像。 圖 1:使用 Planet 插件下載衛星圖像 圖 2:下載圖像的日期和傳感器選擇 我查閱的研究中指出,使用無降水時期的衛星圖像對于水質測定…

Docker部署前后端分離項目——多項目共享環境部署

目錄 一、簡介 二、文件目錄結構 三、前端部署流程(多nginx) 3.1 前端打包 3.2 編寫部署文件——項目1(consult-system) 3.3 編寫部署文件——項目2(person-system) 3.4 前端部署至linux服務器 3.5…

學習筆記(39):結合生活案例,介紹 10 種常見模型

學習筆記(39):結合生活案例,介紹 10 種常見模型線性回歸只是機器學習的 “冰山一角”!根據不同的任務場景(分類、回歸、聚類等),還有許多強大的模型可以選擇。下面我用最通俗易懂的語言,結合生活案例&#…

BabyAGI 是一個用于自構建自主代理的實驗框架

這個最新的 BabyAGI 是一個用于自構建自主代理的實驗框架 核心是一個新的函數框架 (functionz),用于存儲、管理和執行數據庫中的函數。它提供了一個基于圖形的結構,用于跟蹤導入、依賴函數和身份驗證密鑰,并具有自動加…

商業秘密視域下計算機軟件的多重保護困境

作者:邱戈龍、柯堅豪重慶商業秘密律師廣東長昊律師事務所引言:計算機軟件保護的復雜性 在商業秘密保護的宏大版圖中,計算機軟件因其技術密集性和創新性占據著特殊地位。軟件的真正價值不僅在于其代碼本身,更在于其背后的流程、邏…

深入理解 Spring Boot 自動配置原理

Spring Boot 之所以能“開箱即用”,其核心就在于 自動配置機制(Auto Configuration)。本文將深入剖析 Spring Boot 自動配置的工作原理,從注解入手,再到底層的源碼機制,揭開 Spring Boot 背后的“魔法”。 …

Ubuntu18.04開機啟動執行腳本

#!/bin/bash # 運行 .NET Core 應用程序 dotnet /home/bruce/atg/SmartConsole.dll &# 打開瀏覽器 firefox 給文件權限sudo chmod 777 start.sh運行gnome-session-properties打開系統自帶的一個啟動程序

c語言進階 字符函數和字符串函數

字符函數和字符串函數字符函數和字符串函數1. strlenstrlen 函數詳解模擬實現1.計數器方式2.不能創建臨時變量計數器(遞歸)3.指針-指針的方式2. strcpystrcpy 函數詳解模擬實現3. strcatstrcat 函數詳解模擬實現4. strcmpstrcmp 函數詳解模擬實現5. strn…

(LeetCode 每日一題) 1233. 刪除子文件夾 (排序)

題目:1233. 刪除子文件夾 思路:排序,時間復雜度0(L*nlogn)。 文件夾a的子文件b,b字符串字典序列一定是大于a的,所以直接將字符串數組folder升序排序。每次只需判斷當前字符串,是否是父文件夾數組v最后一個…

集成算法學習bagging,boosting,stacking

baggibg(rf隨機森林) adaboostibg 用來展示 Project Jupyter | Home 展示源碼 Eclipse IDE | The Eclipse Foundation Eclipse 下載 |Eclipse 基金會 教程8-Adaboost決策邊界效果_嗶哩嗶哩_bilibili (23 封私信) 圖解機器學習神器:Scikit-Learn - 知乎 Baggi…

HOOPS SDK賦能PLM:打造全生命周期3D數據管理與協作能力

在制造業和工業領域,產品全生命周期管理(PLM) 已成為驅動企業數字化轉型、提升創新力與運營效率的核心引擎。一個高效的PLM平臺不僅需要管理海量的設計數據,還必須在設計、制造、供應鏈、銷售和服務等多個環節之間無縫流轉信息&am…

解決 Selenium 頁面跳轉過快導致的內容獲取問題:從原理到實踐

在使用 Selenium 進行網頁自動化操作時,很多開發者都會遇到一個頭疼的問題:頁面還沒加載完,代碼就已經執行到下一句了。結果要么是元素找不到,要么是獲取的內容不完整,甚至直接拋出異常。今天我們就來聊聊如何優雅地解…

【Python練習】051. 編寫一個函數,實現簡單的定時器功能

051. 編寫一個函數,實現簡單的定時器功能 051. 編寫一個函數,實現簡單的定時器功能 代碼說明: 示例運行: 擴展功能 代碼說明: 實現Python定時器的幾種方法 051. 編寫一個函數,實現簡單的定時器功能 以下是一個簡單的Python函數,用于實現定時器功能。這個定時器可以設置…

springboot基礎-demo

1.創建學生信息表 create table stu(id int unsigned primary key auto_increment comment ID,name varchar(100) comment 姓名,age tinyint unsigned comment 年齡,gender tinyint unsigned comment 性別, 1:男, 2:女,score double(5,2) comment 成績,phone varchar(11) comme…

關于transformer的一些疑點總結

殘差連接的作用 Transformer中的殘差連接(Residual Connection)是其深層架構能穩定訓練的核心設計之一,主要通過以下機制發揮作用: 1. 緩解梯度消失,支持深層訓練 梯度保護機制:在反向傳播時,…

【終極指南】解決 Windows 11 更新后 Docker 連接 localhost 奇慢(卡頓、超時十幾秒)的通用方案

聰明人能看得出這是 ai 寫的,但也是我親身實踐的,最后讓 ai 總結寫了一篇,放心食用 一、 結論先行(直接用)問題現象: 升級到某個 Windows 11 版本后,在本地訪問 Docker 容器中部署的任何服務&am…

Stream API

Java 8 引入的 Stream API 是處理集合數據的強大工具,它允許你以聲明式方式處理數據集合,支持各種聚合操作和并行處理。以下是 Stream API 的核心知識點及具體代碼示例: 1. Stream 概述 Stream 是數據渠道,用于操作數據源&#xf…

相機參數的格式與作用

在計算機視覺中,相機標定是非常重要的一步,主要目的是從圖像中恢復出物體的三維信息。為了做到這一點,我們需要了解和使用一系列的數學工具,這些工具描述了相機的成像過程,包括相機的內參、外參、畸變系數、投影矩陣和…