1. 程式人生 > >Redis關鍵點(自動bgrewriteaof)

Redis關鍵點(自動bgrewriteaof)

Redis 2.4版本做了很多功能改進,尤其是aof這塊變動較大。增加了自動的bgrewriteaof,開啟兩個後臺執行緒來避免主執行緒fsync、rename、close等阻塞操作,另外修復了出現重複命令進入aof檔案的bug,下面是基於2.4.1的原始碼aof這塊的改進分析。

舊的版本問題主要有:

  • 1 主執行緒aof的每次fsync(everysecond模式)在高併發下時常出現100ms的延時,這源於fsync必不可少的磁碟操作,即便已經優化多次請求的離散小io轉化成一次大的連續io(sina的同學也反映過這個問題).
  • 2 主執行緒裡backgroundRewriteDoneHandler函式在處理bgrewriteaof後臺程序退出的時候存在一個rename new-aof-file old-aof-file,然後再close old-aof-file的操作, close是一個unlink的操作(最後的引用計數), unlink消耗的時間取決於檔案的大小,是個容易阻塞的系統呼叫.
  • 3 當發生bgsave或者bgrewriteaof的時候主執行緒和子程序同時寫入不同的檔案,這改變了原有連續寫模式,不同寫入點造成了磁碟磁頭的尋道時間加長(其實一個臺物理機多例項也有這個問題, 要避免同一時間點做bgrewriteaof), 這又加長了fsync時間.

在2.4版裡把fsync和close操作都移動到background來執行.

解決問題1

主執行緒僅僅把aofbuf的資料重新整理到aof檔案裡,然後通過bioCreateBackgroundJob函式往這佇列裡插入fsync job,於是原有主執行緒的fsync工作被轉移到後臺執行緒來做,這樣主執行緒阻塞問題就非同步的解決了.

但這又引發了一個問題,主執行緒對同一個fd如果有write操作,後臺執行緒同時在fsync,這兩個執行緒會互相影響. antirez為此做了一定研究,並給出了簡單的解決方案.

為了避免執行緒的互相影響,主執行緒每次write之前都要檢測一下後臺執行緒任務佇列裡是否有fsync操作,如果有則延遲這次aofbuf的flush,延遲flush這個功能,當然會增大丟資料的可能.

解決缺陷2

backgroundRewriteDoneHandler裡同樣的把close old-aof-file的工作交給backgroud thread來執行.

解決缺陷3

引入了延遲bgrewriteaof

來避免與bgsave同時寫檔案,而server.no_appendfsync_on_rewrite引數的設定又避免了bgrewriteaof時主執行緒出現fsync.

自動的bgrewriteaof

為了避免aof檔案過大,我們會週期性的做bgrewriteaof來重整aof檔案。以前我們會額外的配置crontab在業務低峰期執行這個命令,這額外的增加一個workaroud的指令碼任務在大叢集裡是很糟糕的,不易檢查,出錯無法即時發現。

於是這個自動bgrewriteaof功能被直接加到redis的內部。首先對於aof檔案,server物件新增一個欄位來記錄aof檔案的大小server.appendonly_current_size,每次aof發生變化都會維護這個欄位。

bgrewriteaof完畢或者例項啟動載入aof資料後也會呼叫aofUpdateCurrentSize這個函式維護這個欄位,同時會記錄下此時的aof檔案的大小server.auto_aofrewrite_base_size作為基準值,用於接下來判斷aof增長率。

有了當前值和基準值我們就可以判斷aof檔案的增長情況。另外還需要配置兩個引數來判斷是否需要自動觸發bgrewriteaof。

auto_aofrewrite_perc: aof檔案的大小超過基準百分之多少後觸發bgrewriteaof。預設這個值設定為100,意味著當前aof是基準大小的兩倍的時候觸發bgrewriteaof。把它設定為0可以禁用自動觸發的功能。
auto_aofrewrite_min_size: 當前aof檔案大於多少位元組後才觸發。避免在aof較小的時候無謂行為。預設大小為64mb。
兩個引數都是可以在conf裡靜態配置,或者通過config set來動態修改的。

  1. redis 127.0.0.1:6379> config get auto-aof-rewrite-percentage  
  2. 1) "auto-aof-rewrite-percentage"  
  3. 2) "100"  
  4. redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size  
  5. 1) "auto-aof-rewrite-min-size"  
  6. 2) "1048576"  
  7. redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size  
  8. 1) "auto-aof-rewrite-min-size"  
  9. 2) "1048576"  
  10. redis 127.0.0.1:6379> config set auto-aof-rewrite-percentage 200  
  11. OK  
  12. redis 127.0.0.1:6379> config set auto-aof-rewrite-min-size 10485760  
  13. OK  


然後就是觸發檢查的主邏輯,serverCron時間事件中每次都會檢查現有狀態和引數來判斷是否需要啟動bgrewriteaof。

如果aof檔案增長百分率growth大於auto_aofrewrite_perc,則自動的觸發後一個bgrewriteaof。

延遲bgrewriteaof

這是個小的改進,手動觸發的bgrewriteaof的時候如果同時存在bgsave在備份,會推遲這次操走的事件,設定server.aofrewrite_scheduled=1,待到bgsave結束後的下一次serverCron裡才會觸發。

相關推薦

Redis關鍵點自動bgrewriteaof

Redis 2.4版本做了很多功能改進,尤其是aof這塊變動較大。增加了自動的bgrewriteaof,開啟兩個後臺執行緒來避免主執行緒fsync、rename、close等阻塞操作,另外修復了出現重複命令進入aof檔案的bug,下面是基於2.4.1的原始碼aof這塊的改進分析。 舊的版本問題主要有:

Redis關鍵點rehash

是一種高效的資料結構,被廣泛的用在key-value儲存中,Redis的dict其實就是一個典型的hash table實現。 是在hash table的大小不能滿足需求,造成過多hash碰撞後需要進行的擴容hash table的操作,其實通常的做法確實是建立一個額外的ha

Selenium2+python自動化23-富文本自動發帖【轉載】

成功 正文 地址 sel 代碼 登錄 post ges appdata 前言 富文本編輯框是做web自動化最常見的場景,有很多小夥伴遇到了不知道無從下手,本篇以博客園的編輯器為例,解決如何定位富文本,輸入文本內容 一、加載配置 1.打開博客園寫隨筆,首先需

Selenium2+python自動化23-富文本自動發帖

方法 之前 成功 height ble keys send -i 可能 前言 富文本編輯框是做web自動化最常見的場景,有很多小夥伴遇到了不知道無從下手,本篇以博客園的編輯器為例,解決如何定位富文本,輸入文本內容 一、加載配置 1.打開博客園寫隨筆,首先需

PHP規範PSR4自動載入介紹

本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC 2119中的描述進行解釋。 1 概述 此PSR描述了從檔案路徑自動載入類的規範。它完全可互操作,除了包括PSR-0在內的任何其他自動載入規範外,還可以使用它。此P

搭建redis叢集-偽分散式

安裝redis #關閉防火牆並且安裝iptables(防火牆) 並在防火牆中新增規則,也可以用firewalld.service 防火牆 #如果是用firewalld.service 的防火牆的話下面的步驟可以忽略 # service iptables save The service com

5Spring學習記錄---Spring_bean自動裝配

XML配置裡的bean自動裝配 在非自動裝配下,我們的xml配置檔案是這樣的,這裡有三個bean,car(車),addres(地址),person(人)。person引用錢兩個bean。 <bean id="car" class="jjh.test.autowire.Car" p:ba

C# Winform下一個熱插拔的MIS/MRP/ERP框架14自動更新

對於軟體來說,啟用自動更新是非常必要的。 根據軟體的應用場景,我們可以設計不同的更新模型。 目前,IMES框架執行在.Net framework 4.0下面,使用的Win系統版本在Win7,域內管控,平時業務調整也不是很頻繁。 所以,我的更新很粗放,就是刪除舊檔案,拷貝新檔案: 1、更新檔案放置在檔案

SpringBoot通過JedisCluster連線Redis叢集分散式專案

分散式專案 SpringBoot + Redis使用 現在開發流行微服務、分散式,基於這種情況需要使用redis不想每個專案都去寫重複的程式碼,所以我在工具包中封裝了redis這一塊的連線,但是問題是所有的專案都會依賴我的基礎包,卻不是所有的專案都要使用redis。所以我需要根據業務

REDIS學習3.2spring boot 使用redis作為快取

一,指定主鍵的生成規則 在3.1的基礎上修改RedisConfig @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport {     @Be

skill——zbbix自動發現

 自動發現 1.自動發現的原理 網路發現由兩個步驟組成:發現與動作 發現:zabbix 週期性的掃描在網路發現規則中定義的 IP 段;為每一個規則配置自身的檢查頻率,並且為每一個規則定義一個對指定 IP 段的服務檢查集 動作:是對發現的主機進行設定的過程,常用的動作有新增、刪除、啟動、停

【PHP學習筆記】Laravel動態路由自動路由

動態路由有利有弊, 利 方便,可不用配置路由 。。。。。。好像沒了 弊 寫了很多controller,不太方便檢視到底有多少對外暴露的介面。 不方便對不同介面設定不同規則 不方便自定義請求方式等 。。。。以及很多不方便的弊端

Linux+git+springboot+maven 實現自動更新程式碼自動部署

 思路:首先是在linux伺服器上建立一個git倉庫,然後克隆程式碼到倉庫,寫一個指令碼先拉取程式碼,在構建最後部署 1. 建立git倉庫     建立一個資料夾執行 git init 命令,初始化倉庫 2. 克隆程式碼    

redis簡介無圖

第1章 NoSQL 什麼是 NoSQL NoSQL = Not Only SQL(不僅僅是 SQL) ,也解釋為 non-relational(非關係型資料庫)。在 NoSQL 資料庫中資料之間是無聯絡的,無關係的。資料的結構是鬆散的,可變的。 為什麼使用 NoSQL 關

如何建立一個自己的外掛自動輸入

要實現模擬的手寫輸入,文字一個一個出現在介面上: 1.jq程式碼  <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自動填寫文

golang 操作redis 實戰重操作

1.5通過go語言和redis資料庫進行互動 安裝命令 go get github.com/gomodule/redigo/redis 安裝完成後,回到家目錄建立test.go,把下面程式碼複製到test.go裡面,編譯執行test.go,之後在redis中查

redis desk manager 遠端連線阿里雲伺服器Redis服務Ubuntu18.4

雲服務端 1,雲伺服器上安裝好Redis; 2,進入redis配置檔案路徑修改redis.conf檔案 sudo vim /etc/redis/redis.conf 4,搜尋找到 bind 127.0.0.1,註釋掉; 5,找到protected-mode,yes改為no,

PHP規範PSR4自動載入介紹

本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC 2119中的描述進行解釋。 1 概述 此PSR描述了從檔案路徑自動載入類的規範。它完全可互操作,除了包括PSR-0在內的任何其他自動載入規範外

八 AE攝影自動曝光

數碼相機原理系列學習 AE攝影(自動曝光) AE=Auto Exposure 相機自動決定曝光就是AE模式,AE模式分為,快門優先AE,光圈優先AE,程式自動曝光,3種類型。 快門優先,就是拍照者,按下快門,相機自己設定最適合光圈,光圈優先正好相反,決定了光圈

python監控redis 指令碼結合zabbix

#!/bin/python -- coding:UTF-8 -- import redisimport sys """各個引數的解釋:keyspace_misses //表示未命中數 keyspace_hits //表示命中數 keyspace_hits_rate = keyspace_hits /(k