公開課 redis系列三----redis的copy-on-write機制


redis常用網站:

1.各大數據庫簡介及排行榜: https://db-engines.com/en/ranking 

2. redis中文網站: http://www.redis.cn/

3. redis官網: http://www.redis.io


 

學習方法:

學redis, 乃至任何其他技術, 學會看README

先通看一遍README


基礎常識, redis的編譯安裝

這里說一個重點, README. 走到哪里, 不懂了, 先看readme.

第二個重點: 看腳本, 比如, 我的redis有幾個后台啟動的腳本server-install, 這個工具怎么用? 

  1. 在根目錄README中告訴我們了, 這是一個后台啟動腳本

  2. 腳本怎么用, vi server-install.sh進去看看

 

 

第14條是: ./install_server.sh


 

為什么每次都要執行make

其實make時, 文件夾下一定有一個文件叫Makefile

 

 

redis下載下來就有Makefile文件, 但nginx下載下來的時候沒有這個文件, 我們要執行./configure來生成makefile文件

這就是為什么有些軟件安裝要直接使用make,而有些要先試用configure

 


二. strace工具和redis 的copy-on-write原理

strace : 監控系統內核進程的工具

 

首先, 講一個工具strace. Linux的一個進程工具

這個工具的作用是: 用來最終redis的進程

可以參考這個文章: https://www.linuxidc.com/Linux/2018-01/150654.htm

比如,我們要追蹤redis啟動后的進程

strace -ff -o /usr/local/ooxx/out ./src/redis-server
ff: 表示追蹤所有的進程和線程
-o: 表示日志輸出的文件路徑下的文件名 out是一個文件名的前綴, 如果有多個進程或線程, 以out開頭

redis成功啟動后,進程id是16023

 

我們去 /usr/local/ooxx目錄下查看進程文件, 我們看到有這樣四個文件

 

 這里在介紹一個操作系統內核的命令/proc

 

proc這是一個操作系統內核

16023: 是我們啟動的線程

他里面有一個task目錄: 這里面是16023下啟動的工作進程和線程

 

 我們看到有4個工作的線程

和/usr/local/ooxx/下out的輸出是一樣的

------------------

下面舉例: 

redis持久化數據到磁盤的時候, 會新開一個進程. 然后用新的進程去執行持久化的操作. 我們用strace來追蹤一下這個新創建的進程

第一步: 打開客戶端, 執行bgsave

 

然后查看redis打印的日志輸出

 

 我們來分析一下執行bgsave打印的日志

Background saving started by pid 17042: 后台保存開始, 在17042這個進程上. 這個進程之前沒有, 是新創建的
DB saved on disk: 數據已經保存到磁盤上
RDB: 0 MB of memory used by copy-on-write: 0M內存數據使用copy-on-write的方式被使用
Background saving terminated with success: 保存成功, 進程中斷

首先這里創建了一個新的線程17042. 

我們來看看,是不是創建了一個新的線程

 

 這個進程怎么來的呢? 肯定是主進程創建的, 我們來看看. vi out.16023.

 

 果然有17042這個進程. strace中輸出的每一行都是一句命令. 我們看看創建17042這個進程使用的是什么命令? clone

這是redis后台執行持久化時使用的方式: copy-on-write. 

那么, 什么是copy-on-write呢? copy-on-write的原理. 

redis有一個主進程, 在寫數據, 這時候有一個命令過來了, 說要把數據持久化到磁盤. 

 

 我們知道redis的worker是單線程的, 如果要持久化這個行為也放在單線程里, 那么如果需要持久化數據特別多, 將會影響用戶的使用. 所以單開一個進程專門來做持久化的操作.

那么寫數據, 寫什么呢? 肯定是要把redis內存中的數據寫入. 這時候, 其實redis內存中的數據保存的是一個虛擬地址. 他真實指向的是物理內存的地址(綠色部分)

 

 這時候, 要拷貝, 就是把真實數據的地址拷貝一份到需要持久化的進程中

 

其實持久化進程這個時候只是指向了數據的地址, 內存消耗並不多. 如果這時候, 原來的數據修改了, 怎么辦呢?

redis會開辟一塊新的空間, 讓寫數據的地址指向新的空間

 

 這樣就不會影響持久化進程需要持久化的數據了.

 這就是copy-on-write機制

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM