項目常見面試問題
一、你的項目中緩存粒度是如何選擇的?
緩存粒度一共分為4種. 1.緩存某個數值:一個鍵只保存一個值,性價比較低,使用率低,如果存儲的話我們使用redis的String 2.緩存數據對象:數據庫記錄對應的具體數據,優點是可以多次復用,String,hash 3.緩存數據集合:數據庫查詢對應的結果集,可以和數據對象配合使用,方便數據對象的重用,hash,list,set,zset,String(zset,String) 4.緩存試圖響應:試圖返回的相應數據,復用性比較差,String 所以我們項目中主要對數據集合+數據對象進行緩存,他們的優點是復用性強,節省內存空間.
二、使用過redis的那些格式做過緩存,其他應用場景和優缺點是什么?
包括list,zset,set,hash和json字符串 其中我們使用過json字符串和zset set用來存放無序去重的數據, 如果有判斷是否存在的需求 zset有排序的需要list,如果說是按時間查詢, 查詢的結果固定, 不需要分頁的情況下,我們使用list因為查詢的比較快 但如果有額外排序要求, 而且需要分頁, 我們使用zset(查詢時間跟查詢的長度和數據量有關,跟查詢區別無關, 查詢速度比較均衡), 增加數據效率和存儲的數據量負相關,數據量越大,添加時間越長,查詢數據效率和存儲的數據量負相關,並且和查詢的結果集數據量有關 json字符串需要進行轉換,使用pickle模塊提高性能,無法單獨更新某個字段,節省空間
三、生產環境下緩存數據redis滿了怎么辦,如何在不停止服務器的前提下擴容?
我們通過Redis的Cluster集群來實現擴展存儲空間,在不停掉Cluster集群環境的情況下通過redis-trib.rb腳本文件來動態的往集群環境中增加主,從節點,也可以動態的從集群環境中刪除節點 配置連接https://www.cnblogs.com/PatrickLiu/p/8473135.html 1. 創建兩個redis實例, 修改配置文件ip和端口號 2. 把創建的兩個實例添加到cluster集群中# ruby redis-trib.rb add-node 192.168.127.130:7006 192.168.127.130:7000 3. cluster nodes 進行驗證節點 , (默認都是主master) 4. 從主節點master上抽取一些slots分給要加入的這個主節點 # ruby redis-trib.rb reshard 192.168.127.130:7000 5. 選擇接收數據槽的節點和數據槽產生的方式 選擇all 6. 執行分配計划 yes_ 7. 增加這從節點7007到集群中 # ruby redis-trib.rb add-node 192.168.127.130:7007 192.168.127.130:7000 8. 將從7007節點作為主節點的從節點實現主從配置 進入 7007redis 執行> cluster replicate 71ecd970838e9b400a2a6a15cd30a94ab96203bf(這里是主節點的ID) 首先把redis的 maxmemory 調到最大, 然后把這個maxmemory-policy調成LFU淘汰策略 使用過期策略和緩存淘汰機制 過期策略中選擇惰性過期+定期過期(每100ms對設置了過期時間的數據隨機查詢並刪除過期數據) 緩存淘汰中有LFU和LRU.LFU:優先淘汰不是頻繁使用的數據,有定期衰減這個機制,由於消費較高, 所以我們基本會選擇LRU:優先淘汰不是最近使用的數據.淘汰策略maxmemory-policy volatile-lru
四、緩存穿透和緩存雪崩是什么,如何解決?
緩存穿透,是指查詢一個數據庫一定不存在的數據。正常的使用緩存流程大致是,數據查詢先進行緩存查詢,
如果key不存在或者key已經過期,再對數據庫進行查詢,並把查詢到的對象,放進緩存。如果數據庫查詢對象為空,則不放進緩存. 解決辦法:1.對於數據庫中不存在的數據,也對其在緩存中設置默認值一般過期時間會比較短 2.可以設置一些過濾規則, 如布隆過濾器(算法, 用於判斷數據是否包含在集合中), 將所有可能的值錄入過濾器, 如果不包含直接返回None, 有誤殺概率 緩存雪崩,是指在某一個時間段,緩存集中過期失效。 1.設置過期時間時,添加隨機值,讓過期時間進行一定程度分散 2.多級緩存的方式來處理 3.利用鎖/隊列的形式
五、項目中使用的緩存模式是什么,遇到過哪些問題?
1.Cache Aside 更新模式(同時更新緩存和數據庫) 更新丟失(先更新數據庫,后刪除緩存), 緩存穿透, 緩存雪崩 2.Read/Write Through 更新模式(通讀通寫) 應用程序只需要維護緩存,數據庫的維護工作由緩存代理 read through : 在查詢操作中更新緩存,也就是說,當緩存失效的時候,Cache Aside 模式是由調用方負責把數據加載入緩存,而 Read Through 則用緩存服務自己來加載。 write through: 和 Read Through 相仿,不過是在更新數據時發生。當有數據更新的時候,如果沒有命中緩存,直接更新數據庫,然后返回。
如果命中了緩存,則更新緩存,然后由緩存自己更新數據庫(這是一個同步操作) 3.Write Behind Caching 更新模式 就是在更新數據的時候,只更新緩存,不更新數據庫,而我們的緩存會異步地批量更新數據庫,這個設計的好處就是直接操作內存速度快。 因為異步,Write Behind Caching 更新模式還可以合並對同一個數據的多次操作到數據庫,所以性能的提高是相當可觀的。
但其帶來的問題是,數據不是強一致性的,而且可能會丟失。另外,Write Behind Caching 更新模式實現邏輯比較復雜,因為它需要確認有哪些數據是被更新了的,哪些數據需要刷到持久層上。
只有在緩存需要失效的時候,才會把它真正持久起來。
六、讀寫分離對事務是否有影響?
對於寫操作包括開啟事務和提交或回滾要在一台機器上執行,分散到多台master執行后數據庫原生的單機事務就失效了。 對於事務中同時包含讀寫操作,與事務隔離級別設置有關,如果事務隔離級別為read-uncommitted 或者 read-committed,讀寫分離沒影響,
如果隔離級別為repeatable-read、serializable,讀寫分離就有影響,因為在slave上會看到新數據,而正在事務中的master看不到新數據。
七、varchar和char的區別,utf8字符集下varchar最多能存多少個字符 ?
char的長度不可變,查詢效率高,可能造成存儲浪費,用於手機號.varchar長度可變,,查詢效率低,節省空間,用於用戶名.在UTF8字符集下最大長度不能超過21845
八、primary key和unique的區別?
unique可空,可以在一個表里的一個或多個字段定義; primary key不可空不可重復,在一個表里可以定義聯合主鍵.
九、什么是外鍵約束?
不使用SQL建立外鍵, 而是定義普通的鍵去記錄主鍵(邏輯外鍵) 仍然可以多表聯查,刪除和更新效率高,但是會有出錯的風險,有程序邏輯來控制.
十、什么是索引?
為了提高查詢速度提供的一種數據結構, 類似書的目錄, 方便快速查詢出數據, 而不是從頭到尾的依次對比,優點:增加查詢速度,缺點:增加數據庫的存儲空間,減慢增刪改速度
十一、索引的分類?
普通索引index:不要用可空列作為索引, 易出錯. 適合數據量超過300的表,經常與其他表進行連接的表,經常出現在Where子句中的字段,選擇性高的字段和小字段.頻繁進行數據操作的表,不要建立太多的索引;適用於改動小,查詢多的場景. 聯合索引:聯合索引必須符合最左原則, 否則無效. 主鍵索引:創建主鍵后自動生成 唯一索引:設置唯一約束后自動生成 外鍵索引:設置外鍵約束后自動生成
十二、索引的原理
Mysql的索引存儲結構為B+tree結構 平衡二叉樹. 聚簇索引: 主鍵B+樹在葉子節點直接存儲的是數據行, InnoDB引擎使用. 優點: 主鍵查詢的速度非常快 缺點: 增刪改比較慢,其它的主鍵查詢要二次查詢 非聚簇索引: 主鍵B+樹在葉子節點只是存儲真正數據行的地址, 數據行和索引存儲在不同的結構中,MyISAM引擎使用 優點: 增刪改比較快, 非主鍵的查詢也比較快 缺點: 不支持事務
十三、InnoDB的主鍵為什么選擇自增 ?
數據和主鍵索引是綁定在一起的, 主鍵自增就會讓數據順序添加到B+Tree中, 寫完一頁再寫下一頁, 不需要為了索引的排列而移動數據和頁分裂, 並且移動和頁分裂也會降低查詢速度
十四、能不能使用業務字段作為主鍵(業務主鍵) ?
可以, 但不好 使用自增主鍵性能會快很多 業務字段更新頻繁,一旦修改,索引也要跟着變,成本較高 所以一般采用和業務無關的數據充當主鍵(邏輯主鍵)
十五、聯合主鍵
將多個業務鍵聯合定義為主鍵 優點:節省空間 缺點:和業務有關, 頻繁改動,不是自增,性能差,盡量不要用
十六、三范式和反范式設計
第一范式: 字段具有原子性, 不可拆分 第二范式: 依賴於全部主鍵, 而非部分主鍵 第三范式: 只依賴於主鍵, 非主鍵字段互不依賴 目的是減少冗余字段 如果單獨定義字段來記錄,該字段就稱為冗余字段,這種設計稱為反范式設計. 通過加入冗余字段,來提高數據庫的查詢速度,減少關聯查詢,用空間換取時間 范式是武功招式, 如何運用全看自己, 也有缺點, 查詢速度高了,會增加很多寫入操作
十七、分庫分表前后的問題?
分表分庫前的問題, 用戶請求量太大,解決辦法:分散請求到多個服務器上 單庫太大,解決方法:切分成更多更小的庫 單表太大,解決方法:切分成多個數據集更小的表 分表分庫后的問題, 事務支持,分表分庫后,就成了分布式事務 多庫結果集合並 跨庫join
十八、mysql鎖
它的目的是解決並發情況下資源搶奪問題, 維護數據的一致性, mysql的鎖雖然開發者可以手動設置, 但比較影響並發性, 一般會使用樂觀鎖代替,由於mysql會自動使用鎖, 所以需要了解鎖機制, 以便優化數據庫並發能力. 分為行級鎖和表級鎖. 行級鎖:對數據行鎖定, 並發好, 資源消耗多 表級鎖:對整個表鎖定, 並發差, 資源消耗少
十九、鎖和事務,鎖和事務的優化建議
無論操作是否在事務中, 都可以獲取鎖, 只不過在事務中, 獲取的鎖只有執行完事務才會釋放 優化建議: 1.使用讀取已提交事務隔離級別 2.精心設計索引 3.選擇合理的事務大小 4.最好一次性請求足夠級別的鎖 5.約定以相同的順序訪問各表 6.用相等條件訪問數據 7.除非必須,查詢時不要顯式加鎖
二十、行鎖與讀寫權限
行共享鎖:獲取行共享鎖后, 當前事務可以讀,不一定能寫;其他事務可以讀,不能寫. 共享鎖容易出現死鎖陷阱 行排他鎖:獲取后,當前事務既可以讀,也可以寫;其他事務可以讀,不能寫 行鎖是通過給索引加鎖實現的,如果查詢時沒有觸發索引,就會鎖表,使用讀取已提交事務隔離級別,只鎖行,不鎖表
二十一、什么是間隙鎖
對於鍵值在條件范圍內但並不存在的記錄,叫做'間隙' 在擊中索引的情況下,獲取行鎖時,InnoDB不僅會對符合條件的已有數據行加鎖,也會對這個'間隙'加鎖 InnoDB完整的行鎖機制為 下鍵鎖 缺點是會阻塞符合條件的插入操作,目的是防止幻讀. 解決辦法:1.盡量不要對有頻繁插入的表進行范圍條件的檢索 2.使用讀取已提交事務隔離級別 3.使用唯一索引或主鍵索引進行查詢
二十二、mysql事務和事務隔離級別
目的: 保證數據庫安全穩定運行的技術 四大特性: ACID 原子性 一致性 隔離性 持久性 原子性: 要么都成功, 要么都失敗,實現機制是undo log 一致性:操作前后, 系統穩定, 數據一致,原子性不代表一致性: 臟讀/不可重復讀/幻讀: 解決辦法:調整事務級別 提交事務后, 只有一半操作持久化成功: 解決辦法: redo log 隔離性:每個事務是獨立的,相互不會影響,實現機制多版本並發控制+鎖(MVCC+鎖) 持久性:保證事務的執行結果一定能在數據庫中同步完成, 無論數據庫所在硬件是否癱瘓,實現機制: redo log 原子性 持久性 隔離性 實現了一致性 事務隔離級別:四個級別, 只會用到讀已提交和可重復讀這兩個 mysql默認為可重復讀,更建議使用讀取已提交,不會加間隙鎖,索引沒觸發,不會鎖表,只是鎖行,不可重復讀和幻讀問題, 一般不需要管, 如果有強制要求, 加悲觀鎖/樂觀鎖
二十三、MVCC多版本並發控制
簡單來說就是對數據做了多版本控制,事務隔離級別中的RC和RR就是MVCC實現的 RR可重復讀級別: 快照讀: select * from xx: # 在事務中無論讀多少次都和第一次讀的結果一樣 當前讀: select * from xx lock in share mode; select * from xx for update和insert update delete 語句 RC讀取已提交級別: 仍然有快照讀, 事務提交成功的數據可以讀取得到, 但讀不到未提交的數據
二十四、MyISAM 和InnoDB
MyISAM:只支持表級鎖 表讀鎖/共享鎖:獲取后, 其他請求可以讀不能寫,對MyISAM的讀操作,不會阻塞其他用戶對同一表讀請求,但會阻塞對同一表的寫請求; 表寫鎖/排它鎖:獲取后, 其他請求既不能讀也不能寫,對MyISAM的寫操作,則會阻塞其他用戶對同一表的讀和寫操作; 加鎖方式:1.數據庫自動管理,查詢前給設計的表添加讀鎖, 更新前(增刪改)給涉及的表加寫鎖 2.MyISAM在執行查詢語句前,會自動給涉及的所有表加共享鎖,一旦上共享鎖,其他進程就不能獲取排它鎖, 就不能進行寫操作, 在執行更新、刪除、增加操作前,會自動給涉及的表加寫鎖,這個過程並不需要用戶干預 3.MyISAM表的讀操作和寫操作之間,以及寫操作之間是串行的。 4.當一個線程獲得對一個表的寫鎖后,只有持有鎖線程可以對表進行更新操作。其他線程的讀、寫操作都會等待,直到鎖被釋放為止。 InnoDB:支持行級鎖和表級鎖, 優先使用行級鎖 行共享鎖:獲取后, 其他事務也可以獲取目標集的共享鎖, 但不能獲取目標集的排他鎖 行排它鎖:獲取后, 其他事務既不能獲取目標集的共享鎖, 也不能獲取對應的排它鎖 加鎖方式:1.對於查詢語句,innodb不會加任何鎖,也就是可以多個並發去進行查詢的操作,不會有任何的鎖沖突,因為根本沒有鎖。 2.對於增加、刪除、更新操作,innodb會自動給涉及到的數據加排他鎖,只有查詢操作需要我們手動設置排他鎖。 3.執行增刪改前自動加排它鎖 4.查詢語句不需要任何鎖, innoDB也不添加任何鎖 5.增刪改必須獲取排它鎖, 普通查詢不需要獲取任何鎖
二十五、REDO和UNDO
UNDO:作用:1.用於回滾,現實事務的原子性 2.實現多版本並發控制(MVCC) 原理:在數據操作只從之前,先將牽扯到的數據備份到UNDO LOG, 然后再進行數據的操作 如果出現回滾操作,系統可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態 Undo log必須先於數據持久化到磁盤,如果在D,E之間系統崩潰, undo log是完整的,可以用來回滾事務 REDO:記錄的是新數據的備份 作用:保證事務持久性 原理:1 新數據寫入內存緩沖區后,將執行的更新操作寫入redo log,再將數據寫入磁盤(一定發生在redo寫入之后,但未必立即執行) 2.當系統崩潰時,雖然數據沒有寫入磁盤,但是Redo Log已經持久化,系統可以根據Redo log的內容,將所有數據恢復到最新的狀態 3.雖然redo log和寫入數據庫 都是寫入磁盤,但是redo log的性能高於寫入數據庫(redo log只寫入命令,不添加事務的判斷) 數據庫恢復:1.mysql重啟后自動進行 2.先REDO,再UNDO 3.進行恢復時, 3.1 REDO不區分事務,會重復做所有操作(包括未提交的操作和最終回滾的操作) 3.2 然后再由UNDO來回滾未提交和要執行回滾的事務
二十六、數據庫引擎
實現數據存儲的不同解決方案 InnoDB mysql5.5開始 默認 支持事務,支持行級鎖和表級鎖,並發訪問時效率高,支持外鍵約束,插入/更新/主鍵查詢快,需要內存和硬盤多,常規推薦使用 MyISAM:不支持事務,不支持外鍵約束,只支持表級鎖,批量插入/查詢/count速度快 簡單, 適合小型項目和以批量插入和查詢為主的系統(內部管理系統)
二十七、什么是RPC,gRPC?
RPC (遠程過程調同) 是一個計算機通信協議 作用: 可以以函數形式來調用另一台計算機上的程序 優點: 使用自定義的二進制形式進行數據傳輸, 效率極高 應用場景:子系統之間進行數據交互 grpc:谷歌開發的高性能的RPC框架 優點:1.使用http2.0標准, 支持雙向流和多路復用 2.支持多語言和多平台 http2.0利用二進制的分幀層對請求頭,請求體進行分組分包, 這樣就允許在同一個連接可以發送和接收多個請求的數據 主要特點:二進制分幀層,多路復用,頭部壓縮,服務器推送
二十八、APSchedule定時器
分為crontab和apschedule crontab:是linux系統一個內置命令,依賴於linux系統,無動態管理任務,適合於普通的靜態任務. apschedule:獨里的定時器程序,可以方便的管理定時任務,需要動態生成. 支持三種觸發器 date 只執行一次 interval 周期執行 參數時間間隔 cron 周期執行 參數時間
二十九、緩存更新問題
mysql和redis是兩個獨立的系統,在並發環境下,無法保證更新的一致性,解決辦法:更新數據時,先寫入mysql,再刪除緩存,設計分布式鎖或使消息隊列串行處理
三十、緩存有效期和淘汰策略
設置有效期的作用:1.節省空間 2.做到數據弱一致性,有效期失效后,可以保證數據的一致性 過期策略:1.定時過期:效率太低,每個數據都需要設置定時器進行計數 2.惰性過期:查詢時,才去檢查數據的有效期,如果過期,則返回nil,並刪除過期數據 3.定期過期:每隔100ms,隨機取出一部分數據進行過期校驗,如果過期, 刪除數據 redis中選擇惰性過期+定期過期 (每100ms對設置了過期時間的數據隨機查詢並刪除過期數據) LRU:least recently use 優先淘汰不是最近使用的數據 LFU:least frequently use 優先淘汰不是頻繁使用的數據 采用了定期衰減的機制, 防止舊數據始終無法刪除 缺點:需要每條數據維護一個使用計數,還需要定期衰減
三十一、為什么不用定時過期策略?
定時過期,用一個定時器來負責監視key,過期則自動刪除。雖然內存及時釋放,但是十分消耗CPU資源。在大並發請求下,CPU要將時間應用在處理請求,而不是刪除key,因此沒有采用這一策略.
三十二、定期過期+惰性過期是如何工作的呢?
定期過期,redis默認每個100ms檢查,是否有過期的key,有過期key則刪除。需要說明的是,redis不是每個100ms將所有的key檢查一次,
而是隨機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis豈不是卡死)。因此,如果只采用定期過去策略,會導致很多key到時間沒有刪除。 於是,惰性過期派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key如果設置了過期時間那么是否過期了?如果過期了此時就會刪除。
三十三、采用定期過期+惰性過期就沒其他問題了么?
不是的,如果定期過期沒刪除key。然后你也沒即時去請求key,也就是說惰性過期也沒生效。這樣,redis的內存會越來越高。那么就應該采用內存淘汰機制。
三十四、JWE
對稱加密: 代表算法 des 3des aes,速度快 非對稱加密: 代表算范 rsa 速度慢,不適合大型數據加密 加密時,一般公鑰加密,私鑰解密,與簽名相反 私鑰唯一,使用私鑰簽名,公鑰驗簽,可以保證簽名者身份唯一 主要用於數據加密 最佳方案 (JWE) 傳輸的數據使用對稱加密, 生成數據密文, 對稱加密秘鑰是隨機的,為了防止數據篡改,對數據密文進行摘要認證,摘要認證的秘鑰也是隨機的,對稱加密的秘鑰和摘要認證的秘鑰使用非對稱加密進行處理 JWE的耗時遠高於JWS
三十五、為什么使用JWT進行狀態保持?
因為APP不支持狀態保持,狀態保持有同源策略,無法跨服務器傳遞,所以不采用session.session依賴於cookie不安全,session存在於數據庫,用戶多時,影響數據庫性能
三十六、什么是JWT?
JWT不可逆加密部分主要用於數據認證, 防止數據被修改
三十七、CDN加速是對網站所在服務器加速,還是對其域名加速?
CDN是只對網站的某一個具體的域名加速。如果同一個網站有多個域名,則訪客訪問加入CDN的域名獲得加速效果,訪問未加入CDN的域名,或者直接訪問IP地址,則無法獲得CDN效果。 三十八、CDN使用后,原來的網站是否需要做修改,做什么修改? 一般而言,網站無需任何修改即可使用CDN獲得加速效果。只是對需要判斷訪客IP程序,才需要做少量修改。
三十九、如何解決刷新問題?
1.手機號+驗證碼(或帳號+密碼)驗證后頒發接口調用token與refresh_token(刷新token) 2.Token 有效期為2小時,在調用接口時攜帶,每2小時刷新一次 3.提供refresh_token,refresh_token 有效期14天 4.在接口調用token過期后憑借refresh_token 獲取新token 5.未攜帶token 、錯誤的token或接口調用token過期,返回401狀態碼 6.refresh_token 過期返回403狀態碼,前端在使用refresh_token請求新token時遇到403狀態碼則進入用戶登錄界面從新認證。
四十、判斷問題發生在前端還是后端?
如果前端為網頁,可以通過網頁調試工具里面的network判斷 如果前端不是網頁,比如app,通過日志的訪問請求記錄判斷 如果是后端出現的問題,通過pycharm或日志來判斷
四十一、數據庫優化
1.在進行表設計時,可適度增加冗余字段(反范式設計),減少JOIN操作; 2.多字段表可以進行垂直分表優化,多數據表可以進行水平分表優化; 3.選擇恰當的數據類型,如整型的選擇; 4.對於強調快速讀取的操作,可以考慮使用MyISAM數據庫引擎; 5.對較頻繁的作為查詢條件的字段創建索引;唯一性太差的字段不適合單獨創建索引,即使頻繁作為查詢條件;更新非常頻繁的字段不適合創建索引; 6.編寫SQL時使用上面的方式對SQL語句進行優化; 7.使用慢查詢工具找出效率低下的SQL語句進行優化; 8.構建緩存,減少數據庫磁盤操作; 9.可以考慮結合使用內在型數據庫,如Redis,進行混合存儲。
四十二、Redis事務
語法: 1.MULTI:開啟事務, 后續的命令會被加入到同一個事務中 事務中的操作會發給服務端, 但是不會立即執行, 而是放到了該事務的對應的一個隊列中, 服務端返回QUEUED 2.EXEC:執行EXEC后, 事務中的命令才會被執行,事務中的命令出現錯誤時, 不會回滾也不會停止事務, 而是繼續執行 3.DISCARD:取消事務, 事務隊列會清空, 客戶端退出事務狀態 ACID: 1.原子性: 不支持, 不會回滾並且有錯誤也會繼續執行 2.隔離性: 支持, 單進程,單線程, 事務中的命令順序執行, 並且不會被其他客戶端(事務)打斷(先EXEC的先執行)在事務中的會一次性執行完再執行下一個命令(事務) 3.持久性:不支持, redis數據丟失 4.一致性: 不支持, 如果強制使用一致性,需要加樂觀鎖(watch監聽) watch:redis實現的樂觀鎖 可以實現秒殺超賣需求 事務開啟前, 設置對數據的監聽, EXEC時, 如果發現數據發生過修改, 事務會自動取消 事務EXEC后, 無論成敗, 監聽會被移除 setnx和悲觀鎖:setnx鍵不存在,才會設置成功
四十三、Redis持久化
分為RDB快照存儲和AOF只追加文件 RDB:將內存中的所有數據 完整的保存到硬盤中,配置中設置自動持久化策略 優點:方便數據備份:由於保存到單獨的文件中,易於數據備份 寫時復制:子進程單獨完成持久化操作,父進程不參與IO操作, 最大化redis性能 恢復大量數據時,速度優於AOF 缺點:不是實時保存數據,如果redis意外停止工作,則可能會丟失一段時間的數據 數據量大時,fork進程會比較慢,持久化時使redis響應速度變慢 AOF:只追加而不是全部重新寫入,追加命令而不是數據 優點:更可靠 默認每秒同步一次操作,最多丟失一秒數據 可以進行文件重寫,以避免AOF文件過大 缺點:相同數據集,AOF文件比RDB體積大,恢復速度慢 除非是不同步情況,否則普遍要比RDB速度慢
四十四、如何選擇RDB和AOF?
對於更新頻繁,一致性要求不是非常高的數據可以選擇使用redis進行持久化存儲 RDB or AOF: 數據安全性要求高, 都打開 可以接受短時間的數據丟失, 只使用RDB 即使使用AOF,最好也開啟RDB,因為便於備份並且回復速度快,bug更少 使用redis進行一部分數據的持久化存儲 兩種持久化機制都開啟
四十五、什么是哨兵機制?
監控redis服務器的運行狀態,可以進行自動故障轉移,實現高可用,與數據庫主從配合使用的機制 特點: 1.獨自的進程, 每台redis服務器應該至少配置一個哨兵程序 2.監控redis主服務器的運行狀態 3.出現故障后可以向管理員/其他程序發出通知 4.針對故障,可以進行自動轉移, 並向客戶端提供新的訪問地址 至少在3台服務器上分別啟動至少一個哨兵 如果只有一台,則服務器宕機后,將無法進行故障遷移 如果只有兩台,一旦一個哨兵掛掉了,則投票會失敗 心跳機制和投票裁決
四十六、什么是集群?
多個節點共同保存數據,它能擴展存儲空間,提高吞吐量,提高寫的性能,不在區分數據庫,只有0號庫,單機默認0-15,不支持事務,管道和多值操作. 要求至少三主三從,要求必須開啟AOF持久化,自動選擇集群節點進行存儲,默認集成哨兵,自動故障轉移 redis集群不能支持事務和WATCH, 並發控制只能自己設計悲觀鎖,集群負責實現緩存設計
四十六、數據庫設計?
索引的原理采用了B+Tree平衡二叉樹結構,有聚簇索引和非聚簇索引,
聚簇索引:主鍵B+樹在葉子節點直接存儲的是數據行, InnoDB引擎使用.優點: 主鍵查詢的速度非常快,缺點: 增刪改比較慢,其它的主鍵查詢要二次查詢
非聚簇索引:主鍵B+樹在葉子節點只是存儲真正數據行的地址, 數據行和索引存儲在不同的結構中,MyISAM引擎使用優點: 增刪改比較快, 非主鍵的查詢也比較快
缺點: 不支持事務
所以我們大多數的表都使用了聚簇索引和InnoDB引擎,因為InnoDB引擎支持事務,可以進行事務回滾,恢復速度快,還支持行級鎖和表級鎖,
提高並發訪問時的效率,支持外鍵約束,插入更新主鍵查詢快,但是需要的內存和硬盤多,
而MyISAM引擎不支持事務和外鍵約束,只支持表級鎖,批量插入和查詢速度快,適合小型項目,我們項目中系統公告表因為基本不會修改,
不存在大量並發寫操作,也就不需要行級鎖和事務為數據安全穩定做保障,查詢多,MyISAM的查詢速度會更快.
當初我們嘗試使用業務字段作為主鍵,結果是可以使用,但是不太好,業務字段更新頻繁,一旦修改,索引也要跟着變,成本比較高,所以我們采用和業務無關的數據充當主鍵.