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機制