RHEL6.9組建Redis sentinel叢集遇到兩個問題
今天在元件Redis sentinel 叢集時,遇到兩個問題,之前已經組建多次,都沒碰到類似問題,在解決這兩個問題時,耗費些時間。
問題1. ./redis-server: /lib64/libc.so.6: version `GLIBC_2.14' not found 問題
在將A伺服器 RHEL6.9 上已經編譯好的 Redis-3.0.3 整個目錄,scp 到 RHEL6.9 伺服器B上,
在 A 上能正常執行的redis-server程式,但在 B 伺服器上卻執行失敗,在 B 伺服器redis中的src目錄下使用指令 ldd redis-server
可以看到如下的報錯,
B 伺服器ldd結果:
$ldd redis-server
./redis-server: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./redis-server)
linux-vdso.so.1 => (0x00007ffd3fbc7000)
libm.so.6 => /lib64/libm.so.6 (0x0000003e49a00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003e48a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003e49200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003e48e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003e48600000)
但是在 A 伺服器上進行如上的命令,卻正常,並沒有not found。
A 伺服器ldd結果:
$ldd redis-server
linux-vdso.so.1 (0x00007ffdcdb5b000)
libm.so.6 => /lib64/libm.so.6 (0x0000003940e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003940600000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003940200000)
libc.so.6 => /lib64/libc.so.6 (0x000000393fe00000)
/lib64/ld-linux-x86-64.so.2 (0x000000393fa00000)
這就奇怪了,但是細心觀察,就能發現 /lib64/libc.so.6 () 的值是不一樣的,初步懷疑是由於在 A 機器上編譯環境和 B 上是不一樣的。
利用相關指令檢視 libc.so.6 中是否一樣:
A 伺服器檢視 libc.so.6 內容:
$ strings /lib64/libc.so.6 |grep GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_PRIVATE
B 伺服器檢視 libc.so.6 內容:
$ strings /lib64/libc.so.6 |grep GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_PRIVATE
上述指令對比就能看出,B伺服器的 GLIBC 版本較低,雖然都是RHEL6.9作業系統,但內部庫還是有些不一樣的地方。
對應的解決方法有如下幾種:
- 在 B 的環境中,直接進行 redis 原始碼編譯,生成的可執行檔案能在 B 中成功執行。
- 可以找到與 B 一樣的
strings /lib64/libc.so.6 |grep GLIBC_
的作業系統環境,在其上編譯之後,直接將可執行檔案拷貝到B上執行。 - 升級 B 伺服器的 GLIBC。
- 可在redis原始碼中新增約束,顯式指定所依賴的memcpy函式的GLIBC版本,需新增的約束程式碼如下:
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
,【注意】只需在呼叫函式memcpy的原始檔中加入此約束,該方法讀者可以自行驗證,後面參考連結中有相關部落格介紹。
我是選擇了方法2解決的上述報錯問題,找到一個 strings /lib64/libc.so.6 |grep GLIBC_
和 B 伺服器一樣的內容,重新拷貝redis相關檔案到 B 伺服器中,執行redis程式成功。
問題2. ps -ef 程式 uid 不顯示使用者名稱而是數字
在上述redis於 B 伺服器成功執行後,ps 程式發現第一縱列不是顯示使用者名稱,而是使用者名稱的uid一串數字
$ ps -ef|grep redis
31241 129637 125617 0 17:53 pts/3 00:00:00 ./src/redis-server *:6358
31241 129866 1 0 17:55 ? 00:00:00 ./src/redis-sentinel *:16358 [sentinel]
在使用linux有一段時間,沒遇到過這種現象,一般顯示都直接是使用者名稱,這樣ps就知道該程式是哪個使用者啟動並有許可權停止的。linux中是嚴格區分使用者,不同非root使用者對不同程式檔案目錄等有不同操作許可權,可以使得多使用者使用同一臺伺服器時的安全。
通過man命令檢視ps命令的說明: 8位使用者名稱的賬戶能夠顯示完整的使用者名稱,9位使用者名稱的賬戶就顯示了UID。
當使用者名稱的長度(使用者名稱字串的字元個數)大於8(預設)時,只會顯示使用者的UID, ps的這個長度可以自定義,如下命令:
ps -o ruser=thereisusername -e -o pid,ppid,c,stime,tty,time,cmd|grep xxx
說明:“thereisusername”是自定義填寫的字串,Linux會自動檢查此字串的長度,使用者名稱長度比該字串小的都會顯示使用者名稱。
在Redis使用和學習中,遇到上述問題,特此總結記錄,加深影響,一點一滴積累Redis和Linux相關知識。
參考連結:
https://blog.csdn.net/Jin_Kwok/article/details/80319441?utm_source=blogxgwz7
https://blog.csdn.net/weixin_34294649/article/details/91699158
本人才疏學淺,如有錯誤不當之處,請批評指正,如有侵權,請立即聯絡我進行刪除。
如果能為您帶來一點點幫助,我將十分高興,也多謝您關注:hongmaolinux 和轉發推薦,謝謝!