一鍵源碼編譯安裝redis

本文首發於我的個人網站: https://hewanyue.com/
本文作者: Hechao
本文鏈接: https://hewanyue.com/blog/f2c1a89e.html

  Redis 和 Memcached 是非關係型數據庫也稱爲 NoSQL 數據庫, MySQL、 Mariadb、 SQLServer、 PostgreSQL、 Oracle 數據庫屬於關係型數據(RDBMS, Relational Database Management System)。
  Redis(Remote Dictionary Server)在 2009 年發佈, 開發者 Salvatore Sanfilippo 是意大利開發者, 他本想爲自己的公司開發一個用於替換 MySQL 的產品 Redis, 但是沒有想到他把 Redis 開源後大受歡迎,短短几年, Redis 就有了很大的用戶羣體,目前國內外使用的公司有知乎網、新浪微博、 GitHub 等。
  redis 是一個開源的、 遵循 BSD 協議的、 基於內存的而且目前比較流行的鍵值數據庫(key-value database),是一個非關係型數據庫, redis 提供將內存通過網絡遠程共享的一種服務,提供類似功能的還有 memcache,但相比 memcache, redis 還提供了易擴展、高性能、 具備數據持久性等功能。
  Redis 在高併發、低延遲環境要求比較高的環境使用量非常廣泛, 目前 redis 在 DBEngine 月排行榜 https://db-engines.com/en/ranking 中一直比較靠前,而且一直是鍵值型存儲類的首位。

編譯安裝

  redis在centos版本自帶的yum源中版本比較低,一般都需要我們編譯安裝更高版本的redis。

準備源碼包

  可以先用下載工具去官網下載好源碼包,下載鏈接爲 http://download.redis.io/releases/ 。
  出於穩定性要求,一般來說實際生產中不會選用最新版的redis,避免因爲漏洞造成服務器的安全隱患,所以本次演示,我們選用目前redis4的最新版本,redis-4.0.14來安裝。

編譯安裝

  tar xf redis-4.0.14.tar.gz
  cd redis-4.0.14
  編譯安裝redis的依賴包不多,有make和gcc就夠了。

yum install make gcc -y

  如果是最小化安裝的新系統,忘記安裝gcc的話直接去嘗試編譯安裝redis,就會遇到報錯:

make[3]: Entering directory '/root/redis-4.0.14/deps/hiredis'
gcc -std=c99 -pedantic -c -O3 -fPIC  -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb  net.c
make[3]: gcc: Command not found
make[3]: *** [Makefile:156: net.o] Error 127
make[3]: Leaving directory '/root/redis-4.0.14/deps/hiredis'
make[2]: *** [Makefile:46: hiredis] Error 2
make[2]: Leaving directory '/root/redis-4.0.14/deps'
make[1]: [Makefile:180: persist-settings] Error 2 (ignored)
    CC adlist.o
/bin/sh: cc: command not found
make[1]: *** [Makefile:228: adlist.o] Error 127
make[1]: Leaving directory '/root/redis-4.0.14/src'
make: *** [Makefile:9: install] Error 2

  提示沒裝gcc,再回頭補上,yum install gcc -y,也還是會報錯的。

[root@CentOS8 redis-4.0.14]#make PREFIX=/apps/redis install
cd src && make install
make[1]: Entering directory '/root/redis-4.0.14/src'
    CC adlist.o
In file included from adlist.c:34:
zmalloc.h:50:10: fatal error: jemalloc/jemalloc.h: No such file or directory
 #include <jemalloc/jemalloc.h>
          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [Makefile:228: adlist.o] Error 1
make[1]: Leaving directory '/root/redis-4.0.14/src'
make: *** [Makefile:9: install] Error 2

  這是因爲上次的編譯失敗,有殘留的文件,我們需要清理下,make distclean,然後重新編譯就可以了,make PREFIX=/apps/redis install
  網上也有說可以通過加選項make MALLOC=libc來解決,不過其實是有一些隱患的。首先我們要知道redis 需要使用內存分配器的, 默認是指定內存分配器爲 jemalloc ,make MALLOC=libc 就是指定內存分配器爲 libc ,而jemalloc 內存分配器在實踐中處理內存碎片是要比libc 好的,而且在README.md 文檔也說明到了,jemalloc內存分配器也是包含在源碼包裏面的,可以在deps 目錄下看到 jemalloc 目錄。
  編譯完成後,接下來我們還需要幾步操作。
  創建目錄結構mkdir /apps/redis/{etc,logs,data,run}
  從源碼包中複製配置文件cp redis.conf /apps/redis/etc/
  創建systemctl服務啓動腳本,爲了避免安全隱患,我們還要將redis服務設爲以redis身份啓動,所以還要修改目錄權限

cat > /usr/lib/systemd/system/redis.service <<"END"
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
#ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
END

  創建redis用戶,並修改redis目錄屬主屬組。

groupadd -g 379 redis && useradd -u 379 -g 379 redis -s /sbin/nologin
chown redis.redis -R /apps/redis

  修改PATH變量或者直接用軟鏈接的方式(用一個即可,效果一樣),方便執行redis命令。
  ln -sv /apps/redis/bin/* /usr/local/bin/(軟鏈接)
  echo "PATH=/apps/redis/bin:$PATH" > /etc/profile.d/redis.sh;. /etc/profile.d/redis.sh(改PATH變量)

修改內核參數

  這時redis服務就其實已經搭建完成了,已經可以通過服務腳本進行啓動了。可是如果直接啓動會有一些[warning]信息,而且很有可能在高併發的時候導致redis崩潰。

13636:M 13 Nov 10:37:06.195 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
13636:M 13 Nov 10:37:06.195 # Server initialized
13636:M 13 Nov 10:37:06.195 # 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.
13636:M 13 Nov 10:37:06.195 # 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.

  我們可以通過修改一些內核參數來避免這一風險。

  • TCP backlog 參數控制的是三次握手的時候 server 端收到 client ack 確認號之後的隊列值,redis默認爲511。我們需要將內核的net.core.somaxconn值(系統默認128)更改爲大於511,或將redis的隊列之修改小於128.
  • 將vm.overcommit_memory值改爲1
    0、表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
    1、表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
    2、表示內核允許分配超過所有物理內存和交換空間總和的內存
  • transparent hugepage:
    開啓大頁內存動態分配,需要關閉讓 redis 負責內存管理。

  所以,我們執行下面操作

cat >> /etc/sysctl.conf << END
net.core.somaxconn = 512
vm.overcommit_memory = 1
END
echo never > /sys/kernel/mm/transparent_hugepage/enabled

  至此,redis就正式調試完成,可以正常使用了。

附:一鍵編譯安裝redis腳本

#!/bin/bash
DST="/apps"
#[ -d $DST ] || { echo "install into $DST fail,No such file or directory" ;exit 10;}
[ -a redis-*.tar.* ] || { echo ' the absence of redis.tar.gz' ;exit 1;}
[ -a /usr/lib/systemd/system/redis.service ] && { echo 'redis.service is exist,redis is aready installed' ;exit 2;}
[ -d $DST/redis* ] && { echo "redis is aready installed into $DST/redis" ;exit 3;}
id redis &>/dev/null && { echo 'user redis is exist,redis is aready installed' ; exit 4;} || { groupadd -g 379 redis && useradd -u 379 -g 379 redis -s /sbin/nologin || { echo user 379 is exist ;exit 5; } }
mkdir -p $DST/redis
yum  install  -y make gcc
#yum  install  -y make gcc wget
#wget http://download.redis.io/releases/redis-4.0.14.tar.gz
tar xf redis-*.tar.*
PTH=`find . -name "redis*" -type d |head -n1`
cd $PTH
make PREFIX=$DST/redis install
mkdir $DST/redis/{etc,logs,data,run}
cp redis.conf /apps/redis/etc/
chown redis.redis -R /apps/redis
cat > /usr/lib/systemd/system/redis.service << END
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
#ExecStart=/usr/bin/redis-server /etc/redis.conf --supervised systemd
ExecStart=$DST/redis/bin/redis-server $DST/redis/etc/redis.conf --supervised systemd
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s QUIT \$MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
END
ln -sv $DST/redis/bin/* /usr/local/bin/

cat >> /etc/sysctl.conf << END
net.core.somaxconn = 512
vm.overcommit_memory = 1
END

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

systemctl enable --now redis
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章