數據庫相關
Mybatis的優缺點
優點:
- 基于 SQL 語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影響,SQL 寫在 XML 里,解除 sql 與程序代碼的耦合,便于統一管理;提供 XML 標簽, 支持編寫動態 SQL 語句, 并可重用。
- 與 JDBC 相比,減少了 50%以上的代碼量,消除了 JDBC 大量冗余的代碼,不需要手動開關連接;
- 很好的與各種數據庫兼容( 因為 MyBatis 使用 JDBC 來連接數據庫,所以只要JDBC 支持的數據庫 MyBatis 都支持)。
- 能夠與 Spring 很好的集成;
- 提供映射標簽, 支持對象與數據庫的 ORM 字段關系映射; 提供對象關系映射標簽, 支持對象關系組件維護。
缺點:
- SQL 語句的編寫工作量較大, 尤其當字段多、關聯表多時, 對開發人員編寫SQL 語句的功底有一定要求。
- SQL 語句依賴于數據庫, 導致數據庫移植性差, 不能隨意更換數據庫。
#{}和${}的區別是什么?
#{}是預編譯處理、是占位符, ${}是字符串替換、是拼接符。
Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用 PreparedStatement 來賦值;
Mybatis在處理${}時,會將sql中的${}替換成變量的值,調用 Statement 來賦值;
使用#{}可以有效的防止 SQL 注入, 提高系統安全性。
索引的基本原理
索引用來快速地尋找那些具有特定值的記錄。如果沒有索引,一般來說執行查詢時遍歷整張表。
索引的原理:就是把無序的數據變成有序的查詢
- 把創建了索引的列的內容進行排序
- 對排序結果生成倒排表
- 在倒排表內容上拼上數據地址鏈
- 在查詢的時候,先拿到倒排表內容,再取出數據地址鏈,從而拿到具體數據
索引設計的原則?
查詢更快、占用空間更小
- 適合索引的列是出現在where子句中的列,或者連接子句中指定的列
- 基數較小的表,索引效果較差,沒有必要在此列建立索引
- 使用短索引,如果對長字符串列進行索引,應該指定一個前綴長度,這樣能夠節省大量索引空間,如果搜索詞超過索引前綴長度,則使用索引排除不匹配的行,然后檢查其余行是否可能匹配。
- 不要過度索引。索引需要額外的磁盤空間,并降低寫操作的性能。在修改表內容的時候,索引會進行更新甚至重構,索引列越多,這個時間就會越長。所以只保持需要的索引有利于查詢即可。
- 定義有外鍵的數據列一定要建立索引。
- 更新頻繁字段不適合創建索引
- 若是不能有效區分數據的列不適合做索引列(如性別,男女未知,最多也就三種,區分度實在太低)
- 盡量的擴展索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那么只需要修改原來的索引即可。
- 對于那些查詢中很少涉及的列,重復值比較多的列不要建立索引。
- 對于定義為text、image和bit的數據類型的列不要建立索引。
事務的基本特性和隔離級別
事務基本特性ACID分別是:
原子性指的是一個事務中的操作要么全部成功,要么全部失敗。
一致性指的是數據庫總是從一個一致性的狀態轉換到另外一個一致性的狀態。
隔離性指的是一個事務的修改在最終提交前,對其他事務是不可見的。并發事務互不干擾,確保事務獨立執行。
持久性指的是一旦事務提交,所做的修改就會永久保存到數據庫中。在數據庫中,隔離級別用于定義并發事務之間的交互程度,特別是如何處理事務執行過程中對數據的訪問和修改。不同的隔離級別會影響到事務的并發性和數據一致性。
● read uncommit ?讀未提交,可能會讀到其他事務未提交的數據,也叫做臟讀。 用戶本來應該讀取到id=1的用戶age應該是10,結果讀取到了其他事務還沒有提交的事務,結果讀取結果age=20,這就是臟讀。
● read commit ?讀已提交,兩次讀取結果不一致,叫做不可重復讀。 不可重復讀解決了臟讀的問題,他只會讀取已經提交的事務。 用戶開啟事務讀取id=1用戶,查詢到age=10,再次讀取發現結果=20,在同一個事務里同一個查詢讀取到不同的結果叫做不可重復讀。
● repeatable read ?可重復復讀,這是mysql的默認級別,就是每次讀取結果都一樣,但是有可能產生幻讀。
● serializable ?串行,一般是不會使用的,他會給每一行讀取的數據加鎖,會導致大量超時和鎖競爭的問題。
什么是MVCC
MVCC(Multi-Version Concurrency Control,多版本并發控制)?是一種用于數據庫管理系統的并發控制機制,旨在提高數據庫的并發性能,同時避免讀寫沖突。MVCC 的核心思想是通過維護數據的多個版本來實現并發訪問,而不是通過加鎖來阻塞其他操作。
MVCC(Multi-Version Concurrency Control ,多版本并發控制)指的就是在使用READ COMMITTD、REPEATABLE READ這兩種隔離級別的事務在執行普通的SEELCT操作時訪問記錄的版本鏈的過程。可以使不同事務的讀-寫、寫-讀操作并發執行,從而提升系統性能。
簡述MyISAM和InnoDB的區別
MyISAM 和 InnoDB 是 MySQL 中常用的兩種存儲引擎
MyISAM:
●不支持事務,但是每次查詢都是原子的;
●支持表級鎖,即每次操作是對整個表加鎖;
●存儲表的總行數;
●一個MYISAM表有三個文件:索引文件、表結構文件、數據文件;
●采用非聚集索引,索引文件的數據域存儲指向數據文件的指針。輔索引與主索引基本一致,但是輔索引不用保證唯一性。
InnoDb:
●支持ACID的事務,支持事務的四種隔離級別;
●支持行級鎖及外鍵約束:因此可以支持寫并發;
●不存儲總行數;
●一個InnoDb引擎存儲在一個文件空間(共享表空間,表大小不受操作系統控制,一個表可能分布在多個文件里),也有可能為多個(設置為獨立表空,表大小受操作系統文件大小限制,一般為2G),受操作系統文件大小的限制;
●主鍵索引采用聚集索引(索引的數據域存儲數據文件本身),輔索引的數據域存儲主鍵的值;因此從輔索引查找數據,需要先通過輔索引找到主鍵值,再訪問輔索引;最好使用自增主鍵,防止插入數據時,為維持B+樹結構,文件的大調整。
索引覆蓋是什么
索引覆蓋(Index Covering) 是指在數據庫查詢過程中,查詢所需的所有數據都可以通過索引來獲取,而無需訪問表的實際數據行。
也就是說,查詢可以通過僅掃描索引(而不訪問表數據)來返回結果,從而提高查詢性能。
覆蓋索引與常規索引的對比
- 常規索引:查詢時,數據庫首先使用索引來定位數據行的位置,然后通過回表操作從數據表中讀取完整的行數據。
- 覆蓋索引:查詢時,所有需要的數據都可以從索引本身中獲取,不需要回表,從而提高查詢性能。
最左前綴原則是什么
當一個SQL想要利用索引是,就一定要提供該索引所對應的字段中最左邊的字段,也就是排在最前面的字段,比如針對a,b,c三個字段建立了一個聯合索引,那么在寫一個sql時就一定要提供a字段的條件,這樣才能用到聯合索引,這是由于在建立a,b,c三個字段的聯合索引時,底層的B+樹是按照a,b,c三個字段從左往右去比較大小進行排序的,所以如果想要利用B+樹進行快速查找也得符合這個規則
Innodb是如何實現事務的
Innodb通過Buffer Pool,LogBuffer,Redo Log,Undo Log來實現事務,以一個update語句為例:
- Innodb在收到一個update語句后,會先根據條件找到數據所在的頁,并將該頁緩存在Buffer Pool中
- 執行update語句,修改Buffer Pool中的數據,也就是內存中的數據
- 針對update語句生成一個RedoLog對象,并存入LogBuffer中
- 針對update語句生成undolog日志,用于事務回滾
- 如果事務提交,那么則把RedoLog對象進行持久化,后續還有其他機制將Buffer Pool中所修改的數據頁持久化到磁盤中
- 如果事務回滾,則利用undolog日志進行回滾
B樹和B+樹的區別,為什么Mysql使用B+樹
B樹的特點:
- 內部節點存儲數據和索引:B樹的每個節點包含數據和指向子節點的指針,葉子節點和非葉子節點都能存儲數據。
- 插入和刪除:在 B 樹中,插入和刪除時需要進行內部節點的調整,可能會影響樹的結構。
B+樹的特點:
- 數據僅存儲在葉節點:B+樹中的數據只存儲在葉節點,內部節點只保存索引(指向子節點的指針)。這樣,內部節點的大小通常比 B 樹小。
- 葉節點通過鏈表連接:B+樹的葉節點之間通過鏈表連接,形成一個有序的數據鏈表,方便順序遍歷。
- 所有節點指向葉節點:B+樹的查詢從根節點開始,最終都會到達葉節點,所有的數據都在葉節點中,這提高了查找效率。
MySQL 使用 B+樹 主要是因為它具有以下優勢:
高效的范圍查詢:B+樹的葉節點通過鏈表連接,支持快速的順序遍歷,特別適合進行范圍查詢(比如
BETWEEN
、> <
等)。數據集中在葉節點:所有數據都存儲在葉節點中,非葉節點僅存儲索引,這樣減少了內存的使用和提高了查詢效率。
查詢一致性:所有查詢最終都訪問葉節點,路徑長度一致,查找過程更加穩定和高效。
順序掃描性能好:B+樹的葉節點是有序的,順序掃描時非常高效,特別適合做
ORDER BY
或GROUP BY
操作。綜上,B+樹適合 MySQL 的查詢和索引需求,特別是在處理大量數據時,它提供了更高的性能和更低的資源消耗。
Mysql鎖有哪些,如何理解
按鎖粒度分類:
- 行鎖:鎖某行數據,鎖粒度最小,并發度高
- 表鎖:鎖整張表,鎖粒度最大,并發度低
- 間隙鎖:鎖的是一個區間
還可以分為:
共享鎖:也就是讀鎖,一個事務給某行數據加了讀鎖,其他事務也可以讀,但是不能寫
排它鎖:也就是寫鎖,一個事務給某行數據加了寫鎖,其他事務不能讀,也不能寫還可以分為:
樂觀鎖:并不會真正的去鎖某行記錄,而是通過一個版本號來實現的
悲觀鎖:上面所的行鎖、表鎖等都是悲觀鎖
Mysql慢查詢該如何優化?
- 檢查是否走了索引,如果沒有則優化SQL利用索引
- 檢查所利用的索引,是否是最優索引
- 檢查所查字段是否都是必須的,是否查詢了過多字段,查出了多余數據
- 檢查表中數據是否過多,是否應該進行分庫分表了
- 檢查數據庫實例所在機器的性能配置,是否太低,是否可以適當增加資源
count(*)與count(1)有什么區別
Redis
什么是RDB和AOF
什么是RDB和AOF-CSDN博客
RDB(Redis 數據庫持久化) 和 AOF(Append-Only File) 是 Redis 提供的兩種持久化機制,用于確保數據在 Redis 重啟后能夠恢復。它們分別有不同的工作原理和優缺點,可以根據具體需求選擇合適的方式進行持久化。
RDB:Redis DataBase,在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲。
優點:
- 整個Redis數據庫將只包含一個文件 dump.rdb,方便持久化。
- 容災性好,方便備份。
- 性能最大化,fork 子進程來完成寫操作,讓主進程繼續處理命令,所以是 IO 最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操作,保證了 redis 的高性能
- 相對于數據集大時,比 AOF 的啟動效率更高。
缺點:
- 數據安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候)
- 由于RDB是通過fork子進程來協助完成數據持久化工作的,因此,如果當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是1秒鐘。
AOF:Append Only File,以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄
優點:
- 數據安全,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是異步完成的,其效率也是非常高的,所差的是一旦系統出現宕機現象,那么這一秒鐘之內修改的數據將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的數據變化都會被立即記錄到磁盤中。
- 通過 append 模式寫文件,即使中途服務器宕機也不會破壞已經存在的內容,可以通過 redis-check-aof 工具解決數據一致性問題。
- AOF 機制的 rewrite 模式。定期對AOF文件進行重寫,以達到壓縮的目的
缺點:
- AOF 文件比 RDB 文件大,且恢復速度慢。
- 數據集大的時候,比 rdb 啟動效率低。
- 運行效率沒有RDB高
AOF文件比RDB更新頻率高,優先使用AOF還原數據,AOF比RDB更安全也更大,RDB性能比AOF好,如果兩個都配了優先加載AOF。
Redis的過期鍵的刪除策略
Redis是key-value數據庫,我們可以設置Redis中緩存的key的過期時間。Redis的過期策略就是指當Redis中緩存的key過期了,Redis如何處理。
●惰性過期:只有當訪問一個key時,才會判斷該key是否已過期,過期則清除。該策略可以最大化地節省CPU資源,卻對內存非常不友好。極端情況可能出現大量的過期key沒有再次被訪問,從而不會被清除,占用大量內存。
●定期過期:每隔一定的時間,會掃描一定數量的數據庫的expires字典中一定數量的key,并清除其中已過期的key。該策略是一個折中方案。通過調整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和內存資源達到最優的平衡效果。(expires字典會保存所有設置了過期時間的key的過期時間數據,其中,key是指向鍵空間中的某個鍵的指針,value是該鍵的毫秒精度的UNIX時間戳表示的過期時間。鍵空間是指該Redis集群中保存的所有鍵。)
Redis中同時使用了惰性過期和定期過期兩種過期策略。
簡述Redis事務實現
簡述Redis事務實現-CSDN博客
在 Redis 中,事務是一組被作為一個單元執行的命令集合。與傳統的關系型數據庫事務不同,Redis 的事務沒有提供像 回滾 或 提交 這樣的功能,但它依然通過一些機制確保命令的原子性。
Redis 事務的基本實現方式是通過 MULTI、EXEC、DISCARD 和 WATCH 等命令來控制。以下是 Redis 事務的核心機制:
1. MULTI
- 使用
MULTI
命令來開始一個事務。執行MULTI
后,Redis 會進入一個事務塊模式,此時所有的命令都會被入隊,并不會立即執行。- 所有在事務中的命令都會被放入一個隊列中,直到執行
EXEC
命令時,才會按順序執行。2. 命令入隊
- 在
MULTI
命令之后,后續的 Redis 命令(例如SET
、INCR
、DEL
等)不會立即執行,而是被放入事務隊列中等待。- 每個命令會被當作一個普通的命令進行入隊,不會檢查是否有錯誤,也不會執行(即使命令有語法錯誤,也不會立即反饋)。
3. EXEC
- 使用
EXEC
命令來執行事務中的所有命令。執行EXEC
時,Redis 會按順序執行所有入隊的命令,并返回執行結果。- 原子性:事務中的所有命令要么全部執行成功,要么在
EXEC
時統一執行,不會中途被其他命令打斷。這確保了事務的原子性。4. DISCARD
- 使用
DISCARD
命令可以放棄當前事務,撤銷事務中的所有命令。如果調用了DISCARD
,事務中的命令不會被執行,Redis 會返回 OK。5. WATCH
WATCH
命令用于監視一個或多個鍵。如果這些鍵在事務執行前發生變化(被其他客戶端修改),則EXEC
命令會返回一個空數組,表示事務失敗。- 這種機制類似于樂觀鎖,確保事務在執行時數據不會發生沖突,避免了臟數據。
事務的執行流程
- 客戶端執行
MULTI
開啟事務。- 客戶端接著執行多條 Redis 命令,這些命令都會進入事務隊列。
- 客戶端執行
EXEC
提交事務,Redis 按順序執行事務隊列中的所有命令。- 如果在事務中使用了
WATCH
命令,Redis 會監視指定的鍵。如果在MULTI
和EXEC
之間的某個時刻,監視的鍵被修改,EXEC
會返回空數組,表示事務執行失敗。
Redis 主從復制的核心原理
Redis 主從復制(Master-Slave Replication)是 Redis 提供的一個重要功能,允許一個 Redis 實例作為主節點(Master),將數據同步到一個或多個從節點(Slave)。通過主從復制,Redis 可以實現數據的冗余備份、負載均衡和高可用性。
Redis 主從復制的核心原理-CSDN博客
Redis 主從復制的核心原理是通過 異步復制 實現主節點與從節點之間的數據同步。從節點在連接到主節點后,會執行全量同步和增量同步來保證數據一致性。盡管復制是異步的,但在大多數情況下,Redis 能夠高效地實現數據備份、負載均衡和高可用性。
Redis分布式鎖底層是如何實現的?
Redis 分布式鎖是一種基于 Redis 實現的分布式同步機制,用于在分布式系統中確保多個進程或線程對共享資源的互斥訪問。Redis 分布式鎖的底層實現通常依賴于 Redis 的原子操作和過期時間機制。
- 首先利用setnx來保證:如果key不存在才能獲取到鎖,如果key存在,則獲取不到鎖
- 然后還要利用lua腳本來保證多個redis操作的原子性
- 同時還要考慮到鎖過期,所以需要額外的一個看門狗定時任務來監聽鎖是否需要續約
- 同時還要考慮到redis節點掛掉后的情況,所以需要采用紅鎖的方式來同時向N/2+1個節點申請鎖,都申請到了才證明獲取鎖成功,這樣就算其中某個redis節點掛掉了,鎖也不能被其他客戶端獲取到
Redis分布式鎖底層是如何實現的?-CSDN博客
Redis有哪些數據結構?分別有哪些典型的應用場景?
Redis的數據結構有:
- 字符串:可以用來做最簡單的數據,可以緩存某個簡單的字符串,也可以緩存某個json格式的字符串,Redis分布式鎖的實現就利用了這種數據結構,還包括可以實現計數器、Session共享、分布式ID
- 哈希表:可以用來存儲一些key-value對,更適合用來存儲對象
- 列表:Redis的列表通過命令的組合,既可以當做棧,也可以當做隊列來使用,可以用來緩存類似微信公眾號、微博等消息流數據
- 集合:和列表類似,也可以存儲多個元素,但是不能重復,集合可以進行交集、并集、差集操作,從而可以實現類似,我和某人共同關注的人、朋友圈點贊等功能
- 有序集合:集合是無序的,有序集合可以設置順序,可以用來實現排行榜功能
Redis集群策略
Redis提供了三種集群策略:
- 主從模式:這種模式比較簡單,主庫可以讀寫,并且會和從庫進行數據同步,這種模式下,客戶端直接連主庫或某個從庫,但是但主庫或從庫宕機后,客戶端需要手動修改IP,另外,這種模式也比較難進行擴容,整個集群所能存儲的數據受到某臺機器的內存容量,所以不可能支持特大數據量
- 哨兵模式:這種模式在主從的基礎上新增了哨兵節點,但主庫節點宕機后,哨兵會發現主庫節點宕機,然后在從庫中選擇一個庫作為進的主庫,另外哨兵也可以做集群,從而可以保證但某一個哨兵節點宕機后,還有其他哨兵節點可以繼續工作,這種模式可以比較好的保證Redis集群的高可用,但是仍然不能很好的解決Redis的容量上限問題。
- Cluster模式:Cluster模式是用得比較多的模式,它支持多主多從,這種模式會按照key進行槽位的分配,可以使得不同的key分散到不同的主節點上,利用這種模式可以使得整個集群支持更大的數據容量,同時每個主節點可以擁有自己的多個從節點,如果該主節點宕機,會從它的從節點中選舉一個新的主節點。
對于這三種模式,如果Redis要存的數據量不大,可以選擇哨兵模式,如果Redis要存的數據量大,并且需要持續的擴容,那么選擇Cluster模式。
緩存穿透、緩存擊穿、緩存雪崩分別是什么
緩存中存放的大多都是熱點數據,目的就是防止請求可以直接從緩存中獲取到數據,而不用訪問Mysql。?
- 緩存雪崩:如果緩存中某一時刻大批熱點數據同時過期,那么就可能導致大量請求直接訪問Mysql了,解決辦法就是在過期時間上增加一點隨機值,另外如果搭建一個高可用的Redis集群也是防止緩存雪崩的有效手段
- 緩存擊穿:和緩存雪崩類似,緩存雪崩是大批熱點數據失效,而緩存擊穿是指某一個熱點key突然失效,也導致了大量請求直接訪問Mysql數據庫,這就是緩存擊穿,解決方案就是考慮這個熱點key不設過期時間
- 緩存穿透:假如某一時刻訪問redis的大量key都在redis中不存在(比如黑客故意偽造一些亂七八糟的key),那么也會給數據造成壓力,這就是緩存穿透,解決方案是使用布隆過濾器,它的作用就是如果它認為一個key不存在,那么這個key就肯定不存在,所以可以在緩存之前加一層布隆過濾器來攔截不存在的key
緩存穿透、緩存擊穿、緩存雪崩分別是什么-CSDN博客
Redis和Mysql如何保證數據一致
- 先更新Mysql,再更新Redis,如果更新Redis失敗,可能仍然不一致
- 先刪除Redis緩存數據,再更新Mysql,再次查詢的時候在將數據添加到緩存中,這種方案能解決1方案的問題,但是在高并發下性能較低,而且仍然會出現數據不一致的問題,比如線程1刪除了Redis緩存數據,正在更新Mysql,此時另外一個查詢再查詢,那么就會把Mysql中老數據又查到Redis中
- 延時雙刪,步驟是:先刪除Redis緩存數據,再更新Mysql,延遲幾百毫秒再刪除Redis緩存數據,這樣就算在更新Mysql時,有其他線程讀了Mysql,把老數據讀到了Redis中,那么也會被刪除掉,從而把數據保持一致
Redis的持久化機制
Redis的持久化機制-CSDN博客
Redis單線程為什么這么快
Redis 單線程的高性能主要源于以下幾個方面:
- 避免上下文切換和鎖競爭:沒有線程切換和鎖競爭,減少了系統開銷。
- 事件驅動模型:使用 I/O 多路復用(如 epoll/select)處理多個客戶端請求,提升并發能力。
- 內存存儲和優化數據結構:所有數據存儲在內存,操作簡單且數據結構高效(如哈希表、跳表)。
- 簡化并發模型:單線程避免了多線程的復雜性和同步開銷。
- 內存管理優化:通過內存池等技術減少內存碎片,提升訪問速度。
什么是CAP理論
CAP 理論(CAP Theorem)是分布式系統中的一個基本理論,由計算機科學家 Eric Brewer 提出的。它描述了在一個分布式系統中,一致性(Consistency)、**可用性(Availability)和分區容忍性(Partition Tolerance)**三者之間的關系。
CAP 理論的核心觀點是:在一個分布式系統中,最多只能同時滿足這三者中的兩個,而不能同時滿足全部三個。
CAP 定理
CAP 理論表明,在發生分區時(網絡故障或節點之間的連接丟失),系統必須在 一致性 和 可用性 之間做出權衡。具體來說,系統只能選擇以下兩個特性來保證:
- CA(Consistency + Availability):系統在沒有網絡分區的情況下保證一致性和可用性。但一旦出現分區,系統就不能繼續正常運行。
- CP(Consistency + Partition Tolerance):系統在網絡分區發生時仍然保持一致性和分區容忍性,但在此情況下可能無法保證可用性。
- AP(Availability + Partition Tolerance):系統在網絡分區發生時保持可用性和分區容忍性,但無法保證一致性。
現實中的應用:
- CA 系統:適用于網絡分區不常見,系統較為簡單且不容易發生故障的場景。
- CP 系統:例如 HBase,通常在面對網絡分區時會選擇放棄可用性,保證數據一致性。
- AP 系統:如 Cassandra、MongoDB,在網絡分區時會放棄一致性,確保系統仍然能響應請求。
總結:CAP 定理揭示了分布式系統設計中的基本取舍。選擇一致性、可用性和分區容忍性之間的平衡,取決于系統的需求和應用場景。
什么是BASE理論
由于不能同時滿足CAP,所以出現了BASE理論:
- BA:Basically Available,表示基本可用,表示可以允許一定程度的不可用,比如由于系統故障,請求時間變長,或者由于系統故障導致部分非核心功能不可用,都是允許的
- S:Soft state:表示分布式系統可以處于一種中間狀態,比如數據正在同步
- E:Eventually consistent,表示最終一致性,不要求分布式系統數據實時達到一致,允許在經過一段時間后再達到一致,在達到一致過程中,系統也是可用的
什么是RPC
RPC,表示遠程過程調用,對于Java這種面試對象語言,也可以理解為遠程方法調用,RPC調用和HTTP調用是有區別的,RPC表示的是一種調用遠程方法的方式,可以使用HTTP協議、或直接基于TCP協議來實現RPC,在Java中,我們可以通過直接使用某個服務接口的代理對象來執行方法,而底層則通過構造HTTP請求來調用遠端的方法,所以,有一種說法是RPC協議是HTTP協議之上的一種協議,也是可以理解的。
數據一致性模型有哪些
●強一致性:當更新操作完成之后,任何多個后續進程的訪問都會返回最新的更新過的值,這種是對用戶 最友好的,就是用戶上一次寫什么,下一次就保證能讀到什么。根據 CAP理論,這種實現需要犧牲可用性。
●弱一致性:系統在數據寫入成功之后,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之后 可以讀到。用戶讀到某一操作對系統數據的更新需要一段時間,我們稱這段時間為“不一致性窗口”。
●最終一致性:最終一致性是弱一致性的特例,強調的是所有的數據副本,在經過一段時間的同步之后, 最終都能夠達到一個一致的狀態。因此,最終一致性的本質是需要系統保證最終數據能夠達到一致,而 不需要實時保證系統數據的強一致性。到達最終一致性的時間 ,就是不一致窗口時間,在沒有故障發生的前提下,不一致窗口的時間主要受通信延遲,系統負載和復制副本的個數影響。最終一致性模型根據其提供的不同保證可以劃分為更多的模型,包括因果一致性和會話一致性等。
分布式ID是什么?有哪些解決方案?
在開發中,我們通常會需要一個唯一ID來標識數據,如果是單體架構,我們可以通過數據庫的主鍵,或直接在內存中維護一個自增數字來作為ID都是可以的,但對于一個分布式系統,就會有可能會出現ID沖突,此時有以下解決方案:
- uuid:這種方案復雜度最低,但是會影響存儲空間和性能
- mysql:利用單機數據庫的自增主鍵,作為分布式ID的生成器,復雜度適中,ID長度較之uuid更短,但是受到單機數據庫性能的限制,并發量大的時候,此方案也不是最優方案
- redis、zookeeper:比如redis的自增命令、zookeeper的順序節點,這種方案和單機數據庫(mysql)相比,性能有所提高,可以適當選用
- 雪花算法:一切問題如果能直接用算法解決,那就是最合適的,利用雪花算法也可以生成分布式ID,底層原理就是通過某臺機器在某一毫秒內對某一個數字自增,這種方案也能保證分布式架構中的系統id唯一,但是只能保證趨勢遞增。業界存在tinyid、leaf等開源中間件實現了雪花算法。