新聞中心
深入了解Redis線程工作模式

平泉ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書(shū)合作)期待與您的合作!
Redis作為一種高性能的key-value存儲(chǔ)系統(tǒng),無(wú)疑成為了熱門(mén)技術(shù)之一。Redis快速處理大量數(shù)據(jù)的能力取決于其高效的線程工作模式。本文將深入了解Redis的線程工作模式,以便更好的理解Redis的內(nèi)部工作原理。
Redis的線程模型
Redis從2.8版本開(kāi)始,采用了多線程方式實(shí)現(xiàn)I/O多路復(fù)用,用于處理并發(fā)連接請(qǐng)求。Redis線程數(shù)默認(rèn)為cpu核心數(shù)量。其中,主線程被用于處理客戶端的連接和協(xié)議解析,以及同步的I/O操作。工作線程負(fù)責(zé)處理異步的 I/O 操作(如文件事件),并執(zhí)行在key空間中定義的命令。下圖是Redis多線程架構(gòu)示意圖:

如上圖所示,Redis主線程接收客戶端請(qǐng)求,同時(shí)與工作線程協(xié)作處理I/O讀寫(xiě)。工作線程也處理Redis持久化操作和其他底層任務(wù)。Redis線程模型的優(yōu)點(diǎn)是減少鎖競(jìng)爭(zhēng),在高并發(fā)下性能得到強(qiáng)力保障。
Redis的I/O模型
Redis使用了epoll進(jìn)行I/O多路復(fù)用,以實(shí)現(xiàn)高并發(fā)讀寫(xiě)。epoll采取了邊緣觸發(fā)(EPOLLET)的方式,只有當(dāng)文件描述符狀態(tài)發(fā)生變化時(shí),內(nèi)核才會(huì)通知應(yīng)用程序。
Redis采用epoll的ET模式以減少CPU上下文切換,處理過(guò)程簡(jiǎn)單,效率高,并且避免了遺漏的文件描述符事件。ET模式需要確保讀取或?qū)懭氲木彺鎱^(qū),都應(yīng)該被完整的處理一遍。因此,當(dāng)Redis請(qǐng)求的大小超過(guò)系統(tǒng)默認(rèn)的緩沖區(qū)大小時(shí),redis在異步讀取/寫(xiě)入時(shí),需要進(jìn)行多次的讀寫(xiě)操作,以確保緩沖區(qū)文本被完整地讀出/寫(xiě)入。以下是Redis ET讀寫(xiě)實(shí)現(xiàn)過(guò)程的示意圖:

Redis的AOF持久化模式
Redis主要支持兩種持久化方式:RDB和AOF。不過(guò)本文只討論AOF持久化策略,它也是Redis使用最多的一種策略。AOF的寫(xiě)操作可能會(huì)卡住主進(jìn)程,從而影響性能。為了降低寫(xiě)操作的影響,Redis容器采取了異步AOF持久化模式,即BGREWRITEAOF(后臺(tái)重寫(xiě))。該模式通過(guò)生成新的AOF文件,然后將其追加到原AOF文件中。該過(guò)程在后臺(tái)完成,不會(huì)阻塞Redis的主工作線程。以下為Redis AOF持久化模式示意圖:

從上圖中可以看出,Redis將不太重要的任務(wù)交給了工作線程,并將I/O操作異步化,以避免重要任務(wù)的阻塞。同時(shí),Redis采取了異步AOF持久化模式,以減輕寫(xiě)操作所產(chǎn)生的性能影響。Redis的線程工作模式十分高效,可接受高并發(fā)請(qǐng)求,具有出色的穩(wěn)定性和高可用性。
本文示例代碼:
// 1. mn thread
aeMn()
{
// 等待事件
aeApiPoll();
// …
// 接收到 read 命令后
if (socket_read_pending()) {
// 將命令交給工作線程執(zhí)行
worker_pool.schedule(read_handler, socket_fd);
}
// …
// 在工作線程中處理異步 I/O 請(qǐng)求
worker_pool.run_io_threads();
// …
}
// 2. 工作線程
void run_io_threads()
{
// 利用 poll() 函數(shù)進(jìn)入等待就緒的狀態(tài)
// 和 poll() 函數(shù)類似,這里我們用自己封裝的 async_poll() 函數(shù)
while(true){
// 處理正在執(zhí)行的 IO 請(qǐng)求
process_io_requests();
// 查詢當(dāng)前是否有需要執(zhí)行的操作
if (async_poll(thread_read_fds)) {
// 執(zhí)行每個(gè)客戶端的命令
process_read_commands();
// 執(zhí)行文件事件
process_disk_events();
}
// 執(zhí)行 Redis 的一些常規(guī)操作
process_checkpointing();
process_timers();
process_scroll();
}
}
// 3. 異步 AOF 備份操作
void bg_rewrite_aof()
{
// 創(chuàng)建新文件
aof_file = open(“redis.aof.new”, O_CREAT | O_RDWR, S_IRWXU);
// …
// 異步寫(xiě)入
while(true) {
append_to_file(io_buffer, io_size);
// 寫(xiě)入速度過(guò)快
if (a_socket_send_buffer_full()) {
// 等待套接字寫(xiě)空
a_socket_send_wt_until_unblock();
}
// 壓縮并移動(dòng)文件
compress_and_transfer_approved_files();
}
}
// 4. Redis 的多線程模塊
class WorkerPool {
public:
// 從工作隊(duì)列中取出 worker 開(kāi)始執(zhí)行
void run_worker(Worker& worker) {
pthread_create(worker.tid, NULL, worker.worker_routine, (void*)&tpool);
}
};
int mn() {
WorkerPool tp;
Worker* threads[THREAD_NUM];
for (int i = 0; i
threads[i].tid = i;
threads[i].worker_routine = worker_routine;
tp.run_worker(threads[i]);
}
}
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開(kāi)通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
當(dāng)前名稱:深入了解Redis線程工作模式(redis線程工作模式)
URL網(wǎng)址:http://www.5511xx.com/article/codhpdj.html


咨詢
建站咨詢
