<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis在Linux系統(tǒng)的配置優(yōu)化

          共 8647字,需瀏覽 18分鐘

           ·

          2020-11-07 04:22

          通常來看,Redis開發(fā)和運維人員更加關(guān)注的是Redis本身的一些配置優(yōu)化,例如AOF和RDB的配置優(yōu)化、數(shù)據(jù)結(jié)構(gòu)的配置優(yōu)化等,但是對于操作系統(tǒng)是否需要針對Redis做一些配置優(yōu)化不甚了解或者不太關(guān)心,然而事實證明一個良好的系統(tǒng)操作配置能夠為Redis服務(wù)良好運行保駕護航。

          眾所周知Redis的作者對于Windows操作系統(tǒng)并不感冒,目前大部分公司都會將Web服務(wù)器、數(shù)據(jù)庫服務(wù)器等部署在Linux操作系統(tǒng)上,Redis也不例外。所以接下來介紹Linux操作系統(tǒng)如何優(yōu)化Redis,包含如下七個方面。

          一. 內(nèi)存分配控制

          1. vm.overcommit_memory

          Redis在啟動時可能會出現(xiàn)這樣的日志:

          #?WARNING?overcommit_memory?is?set?to?0!?Background?save?may?fail?under?low?memory?condition.?To?fix?this?issue?add?'vm.overcommit_memory?=?1'?to?/etc/sysctl.conf?and?then?reboot?or?run?the?
          command?'sysctl?vm.overcommit_memory=1'?for?this?to?take?effect.

          在分析這個問題之前,首先要弄清楚什么是overcommit?Linux操作系統(tǒng)對大部分申請內(nèi)存的請求都回復(fù)yes,以便能運行更多的程序。因為申請內(nèi)存后,并不會馬上使用內(nèi)存,這種技術(shù)叫做overcommit。如果Redis在啟動時有上面的日志,說明vm.overcommit_memory=0,Redis提示把它設(shè)置為1。

          vm.overcommit_memory用來設(shè)置內(nèi)存分配策略,它有三個可選值,如下表所示。

          vm.overcommit_memory含義
          0表示內(nèi)核將檢查是否有足夠的可用內(nèi)存。如果有足夠的可用內(nèi)存,內(nèi)存申請通過,否則內(nèi)存申請失敗,并把錯誤返回給應(yīng)用進程
          1表示內(nèi)核允許超量使用內(nèi)存直到用完為止
          2表示內(nèi)核決不過量的("never overcommit")使用內(nèi)存,即系統(tǒng)整個內(nèi)存地址空間不能超過swap+50%的RAM值,50%是overcommit_ratio默認(rèn)值,此參數(shù)同樣支持修改
          注意:本文的可用內(nèi)存代表物理內(nèi)存與swap之和。

          日志中的Background save代表的是bgsave和bgrewriteaof,如果當(dāng)前可用內(nèi)存不足,操作系統(tǒng)應(yīng)該如何處理fork。如果vm.overcommit_memory=0,代表如果沒有可用內(nèi)存,就申請內(nèi)存失敗,對應(yīng)到Redis就是fork執(zhí)行失敗,在Redis的日志會出現(xiàn):

          Cannot?allocate?memory?

          Redis建議把這個值設(shè)置為1,是為了讓fork能夠在低內(nèi)存下也執(zhí)行成功。

          2. 獲取和設(shè)置

          獲?。?/h4>
          cat?/proc/sys/vm/overcommit_memory
          0

          設(shè)置:

          echo?"vm.overcommit_memory=1"?>>?/etc/sysctl.conf
          sysctl?vm.overcommit_memory=1

          3. 最佳實踐

          • Redis設(shè)置合理的maxmemory,保證機器有20%~30%的閑置內(nèi)存。
          • 集中化管理aof重寫和rdb的bgsave。
          • 設(shè)置vm.overcommit_memory=1,防止極端情況下,會造成fork失敗。

          二. swappiness

          1. 參數(shù)說明

          swap對于操作系統(tǒng)來比較重要,當(dāng)物理內(nèi)存不足時,可以swap out一部分內(nèi)存頁,以解燃眉之急。但世界上沒有免費午餐,swap空間由硬盤提供,對于需要高并發(fā)、高吞吐的應(yīng)用來說,磁盤IO通常會成為系統(tǒng)瓶頸。在Linux中,并不是要等到所有物理內(nèi)存都使用完才會使用到swap,系統(tǒng)參數(shù)swppiness會決定操作系統(tǒng)使用swap的傾向程度。swappiness的取值范圍是0~100,swappiness的值越大,說明操作系統(tǒng)可能使用swap的概率越高,swappiness值越低,表示操作系統(tǒng)更加傾向于使用物理內(nèi)存。swap的默認(rèn)值是60,了解這個值的含義后,有利于Redis的性能優(yōu)化。下表對swappiness的重要值進行了說明。

          swapniess策略
          0Linux3.5以及以上:寧愿OOM killer也不用swap
          Linux3.4以及更早:寧愿swap也不要OOM killer
          1Linux3.5以及以上:寧愿swap也不要OOM killer
          60默認(rèn)值
          100操作系統(tǒng)會主動地使用swap
          運維提示:OOM(Out Of Memory) killer機制是指Linux操作系統(tǒng)發(fā)現(xiàn)可用內(nèi)存不足時,強制殺死一些用戶進程(非內(nèi)核進程),來保證系統(tǒng)有足夠的可用內(nèi)存進行分配。

          從下表中可以看出,swappiness參數(shù)在Linux 3.5版本前后的表現(xiàn)并不完全相同,Redis運維人員在設(shè)置這個值需要關(guān)注當(dāng)前操作系統(tǒng)的內(nèi)核版本。

          2. 設(shè)置方法

          swappiness設(shè)置方法如下:

          echo?{bestvalue}?>?/proc/sys/vm/swappiness

          但是上述方法在系統(tǒng)重啟后就會失效,為了讓配置在重啟Linux操作系統(tǒng)后立即生效,只需要在/etc/sysctl.conf追加 vm.swappiness={bestvalue}即可。

          echo?vm.swappiness={bestvalue}?>>?/etc/sysctl.conf

          需要注意/proc/sys/vm/swappiness是設(shè)置操作,/etc/sysctl.conf是追加操作。

          3. 如何監(jiān)控swap

          (1) 查看swap的總體情況

          Linux提供了free命令來查詢操作系統(tǒng)的內(nèi)存使用情況,其中也包含了swap的相關(guān)使用情況。下面是某臺Linux服務(wù)器執(zhí)行free –m(以兆為到位)的結(jié)果,其中需要重點關(guān)注的是最后一行的swap統(tǒng)計,從執(zhí)行結(jié)果看,swap一共有4095M,使用了0M,空閑了4095M。

          ?????????????total???????used???????free?????shared????buffers?????cached
          Mem:?????????64385??????31573??????32812??????????0????????505??????10026
          -/+?buffers/cache:??????21040??????43344
          Swap:?????????4095??????????0???????4095

          在另一臺Linux服務(wù)器同樣執(zhí)行free -m,這臺服務(wù)器開啟了8189M swap,其中使用了5241M。

          ?????????????total???????used???????free?????shared????buffers?????cached
          Mem:?????????24096???????8237??????15859??????????0????????136???????2483
          -/+?buffers/cache:???????5617??????18479
          Swap:?????????8189???????5241???????2947

          (2) 實時查看swap的使用

          Linux提供了vmstat命令查詢系統(tǒng)的相關(guān)性能指標(biāo),其中包含負(fù)載、CPU、內(nèi)存、swap、IO的相關(guān)屬性。但其中和swap有關(guān)的指標(biāo)是si和so,它們分別代表了操作系統(tǒng)的swap in和swap out。下面是執(zhí)行vmstat 1(每隔一秒輸出)的效果,可以看到si和so都為0,代表當(dāng)前沒有使用swap。

          #?vmstat??1
          procs?-----------memory----------?---swap--?-----io----?--system--?-----cpu-----
          ?r??b???swpd???free???buff??cache???si???so????bi????bo???in???cs?us?sy?id?wa?st
          ?1??0??????0?33593468?517656?10271928????0????0?????0?????1????0????0??8??0?91??0??0?
          ?4??0??????0?33594516?517656?10271928????0????0?????0?????0?10606?9647?10??1?90??0??0?
          ?1??0??????0?33594392?517656?10271928????0????0?????0?????0?11490?10244?11??1?89??0??0?
          ?6??0??????0?33594292?517656?10271928????0????0?????0????36?12406?10681?13??1?87??0??0?

          (3) 查看指定進程的swap使用情況

          Linux操作系統(tǒng)中,/proc/{pid}目錄是存儲指定進程的相關(guān)信息,其中/proc/{pid}/smaps是記錄了當(dāng)前進程所對應(yīng)的內(nèi)存映像信息,這個信息對于查詢指定進程的swap使用情況很有幫助。下面以一個Redis實例進行說明 通過info server獲取Redis的進程號process_id:

          redis-cli?-h?ip?-p?port?info?server?|?grep?process_id
          process_id:986

          通過cat /proc/986/smaps查詢Redis的smaps信息,由于有多個內(nèi)存塊信息,這里只輸出一個內(nèi)存塊鏡像信息進行觀察。

          2aab0a400000-2aab35c00000?rw-p?2aab0a400000?00:00?0?
          Size:????????????712704?kB
          Rss:?????????????617872?kB
          Shared_Clean:?????????0?kB
          Shared_Dirty:?????????0?kB
          Private_Clean:????15476?kB
          Private_Dirty:???602396?kB
          Swap:?????????????58056?kB
          Pss:?????????????617872?kB

          其中Swap字段代表該內(nèi)存塊存在swap分區(qū)的數(shù)據(jù)大小。通過執(zhí)行如下命令,就可以找到每個內(nèi)存塊鏡像信息中,這個進程使用到的swap量,通過求和就可以算出總的swap用量。

          cat?/proc/986/smaps?|?grep?Swap
          Swap:?????????????????0?kB
          Swap:?????????????????0?kB

          Swap:?????????????????0?kB
          Swap:????????????478320?kB

          Swap:???????????????624?kB
          Swap:?????????????????0?kB

          4. 最佳實踐

          如果Linux>3.5,vm.swapniess=1,否則vm.swapniess=0,從而實現(xiàn)如下兩個目標(biāo):

          • 物理內(nèi)存充足時候,使Redis足夠快。
          • 物理內(nèi)存不足時候,避免Redis死掉(如果當(dāng)前Redis為高可用,死掉比阻塞更好)。

          三. Transparent Huge Pages

          Redis在啟動時可能會看到如下日志:

          WARNING?you?have?Transparent?Huge?Pages?(THP)?support?enabled?in?your?kernel.?This?will?create?latency?and?memory?usage?issues?with?Redis.?To?fix?this?issue?run?the?command?'echo?never?>?/sys/kernel/mm/transparent_hugepage/enabled'?as?root,?and?add?it?to?your?/etc/rc.local?in?order?to?retain?the?setting?after?a?reboot.?Redis?must?be?restarted?after?THP?is?disabled.

          從提示看Redis建議修改Transparent Huge Pages (THP)的相關(guān)配置,Linux kernel在2.6.38內(nèi)核增加了Transparent Huge Pages (THP)特性 ,支持大內(nèi)存頁(2MB)分配,默認(rèn)開啟。當(dāng)開啟時可以降低fork子進程的速度,但fork之后,每個內(nèi)存頁從原來4KB變?yōu)?MB,會大幅增加重寫期間父進程內(nèi)存消耗。同時每次寫命令引起的復(fù)制內(nèi)存頁單位放大了512倍,會拖慢寫操作的執(zhí)行時間,導(dǎo)致大量寫操作慢查詢。例如簡單的incr命令也會出現(xiàn)在慢查詢中。因此Redis日志中建議將此特性進行禁用,禁用方法如下:

          echo?never?>??/sys/kernel/mm/transparent_hugepage/enabled

          而且為了使機器重啟后THP配置依然生效,可以在/etc/rc.local中追加echo never > /sys/kernel/mm/transparent_hugepage/enabled。

          在設(shè)置THP配置時需要注意:有些Linux的發(fā)行版本沒有將THP放到/sys/kernel/mm/transparent_hugepage/enabled中,例如Red Hat 6以上的THP配置放到/sys/kernel/mm/redhat_transparent_hugepage/enabled中。而Redis源碼中檢查THP時,把THP位置寫死。

          FILE?*fp?=?fopen("/sys/kernel/mm/transparent_hugepage/enabled","r");
          if?(!fp)?return?0;???

          所以在發(fā)行版中,雖然沒有THP的日志提示,但是依然存在THP所帶來的問題。

          echo?never?>??/sys/kernel/mm/redhat_transparent_hugepage/enabled

          四. OOM killer

          OOM killer會在可用內(nèi)存不足時選擇性的殺掉用戶進程,它的運行規(guī)則是怎樣的,會選擇哪些用戶進程“下手”呢?OOM killer進程會為每個用戶進程設(shè)置一個權(quán)值,這個權(quán)值越高,被“下手”的概率就越高,反之概率越低。每個進程的權(quán)值存放在/proc/{progress_id}/oom_score中,這個值是受/proc/{progress_id}/oom_adj的控制,oom_adj在不同的Linux版本的最小值不同,可以參考Linux源碼中oom.h(從-15到-17)。當(dāng)oom_adj設(shè)置為最小值時,該進程將不會被OOM killer殺掉,設(shè)置方法如下。

          echo?{value}?>?/proc/${process_id}/oom_adj

          對于Redis所在的服務(wù)器來說,可以將所有Redis的oom_adj設(shè)置為最低值或者稍小的值,降低被OOM killer殺掉的概率。

          for?redis_pid?in?$(pgrep?-f?"redis-server")
          do
          ??echo?-17?>?/proc/${redis_pid}/oom_adj
          done

          運維提示:

          • 有關(guān)OOM killer的詳細(xì)細(xì)節(jié),可以參考Linux源碼mm/oom_kill.c中oom_badness函數(shù)。
          • 筆者認(rèn)為oom_adj參數(shù)只能起到輔助作用,合理的規(guī)劃內(nèi)存更為重要。
          • 通常在高可用情況下,被殺掉比僵死更好,因此不要過多依賴oom_adj配置

          五. 使用NTP

          NTP(Network Time Protocol)網(wǎng)絡(luò)時間協(xié)議,一種保證不同機器時鐘一致性的服務(wù)。我們知道像Redis Sentinel和Redis Cluster這兩種需要多個Redis實例的類型,可能會涉及多臺服務(wù)器。雖然Redis并沒有對多個服務(wù)器的時鐘有嚴(yán)格的要求,但是假如多個Redis實例所在的服務(wù)器時鐘不一致,對于一些異常情況的日志排查是非常困難的,例如Redis Cluster的故障轉(zhuǎn)移,如果日志時間不一致,對于我們排查問題帶來很大的困擾(注:但不會影響集群功能,集群節(jié)點依賴各自時鐘)。一般公司里都會有NTP服務(wù)用來提供標(biāo)準(zhǔn)時間服務(wù),從而達(dá)到糾正時鐘的效果(如下圖所示),為此我們可以每天定時去同步一次系統(tǒng)時間,從而使得集群中的時間是統(tǒng)一。

          例如每小時的同步1次NTP服務(wù)

          0?*?*?*?*?/usr/sbin/ntpdate?ntp.xx.com?>?/dev/null?2>&1

          六. ulimit

          在Linux中,可以通過ulimit查看和設(shè)置系統(tǒng)的當(dāng)前用戶進程的資源數(shù)。其中ulimit -a命令包含的open files參數(shù),是單個用戶同時打開的最大文件個數(shù)。

          #?ulimit?–a

          max?locked?memory???????(kbytes,?-l)?64
          max?memory?size?????????(kbytes,?-m)?unlimited
          open?files??????????????????????(-n)?1024
          pipe?size????????????(512?bytes,?-p)?8

          Redis允許同時有多個客戶端通過網(wǎng)絡(luò)進行連接,可以通過配置maxclients來限制最大客戶端連接數(shù)。對Linux操作系統(tǒng)來說這些網(wǎng)絡(luò)連接都是文件句柄。假設(shè)當(dāng)前open files是4096,那么啟動Redis時會看到如下日志。

          #?You?requested?maxclients?of?10000?requiring?at?least?10032?max?file?descriptors.
          #?Redis?can’t?set?maximum?open?files?to?10032?because?of?OS?error:?Operation?not?permitted.
          #?Current?maximum?open?files?is?4096.?Maxclients?has?been?reduced?to?4064?to?compensate?for?low?ulimit.?If?you?need?higher?maxclients?increase?‘ulimit?–n’.

          上面的日志解釋如下:

          • 第一行:Redis建議把open files至少設(shè)置成10032,那么這個10032是如何來的呢?因為maxclients的默認(rèn)是10000,這些是用來處理客戶端連接的,除此之外,Redis內(nèi)部會使用最多32個文件描述符,所以這里的10032 = 10000 + 32。
          • 第二行:Redis不能將open files設(shè)置成10032,因為它沒有權(quán)限設(shè)置。
          • 第三行:當(dāng)前系統(tǒng)的open files是4096,所以maxclients被設(shè)置成4096-32=4064個,如果你想設(shè)置更高的maxclients,請使用ulimit -n來設(shè)置。從上面的三行日志分析可以看出open files的限制優(yōu)先級比maxclients大。open files的設(shè)置方法如下:
          ulimit?–Sn?{max-open-files}

          七. TCP backlog

          Redis默認(rèn)的tcp-backlog為511,可以通過修改配置tcp-backlog進行調(diào)整,如果Linux的tcp-backlog小于Redis設(shè)置的tcp-backlog,那么在Redis啟動時會看到如下日志:

          #?WARNING:?The?TCP?backlog?setting?of?511?cannot?be?enforced?because?/proc/sys/net/core/somaxconn?is?set?to?the?lower?value?of?128.

          查看方法:

          cat?/proc/sys/net/core/somaxconn
          128

          修改方法:.

          echo?511?>?/proc/sys/net/core/somaxconn


          本文作者正在招聘:ElasticSearch工程師

          ?

          往期推薦

          MIT黑科技:通過手機記錄的咳嗽數(shù)據(jù)檢測是否感染新冠病毒

          為什么我使用了索引,查詢還是慢?

          10個你可能不曾用過卻很有用的 LINUX 命令

          分享一個Java開發(fā)都用得到的密碼摘要算法包

          程序員編碼時都戴耳機?到底在聽什么?

          Spring Data 發(fā)布更改版本管理方案之后的第一個版本:2020.0.0


          掃一掃,關(guān)注我

          一起學(xué)習(xí),一起進步

          每周贈書,福利不斷

          深度內(nèi)容

          推薦加入


          最近熱門內(nèi)容回顧? ?#技術(shù)人系列

          瀏覽 34
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  w超清无码在线观看 | 韩国成人91 | 三级久久电影 | 日韩无码一区二区网站 | www国产亚洲精品久久网站 |