組建Redis集群遇到`GLIBC_2.14′ not found和ps -ef 不顯示用戶名
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相關知識。
參考鏈接:
//blog.csdn.net/Jin_Kwok/article/details/80319441?utm_source=blogxgwz7
//blog.csdn.net/weixin_34294649/article/details/91699158
本人才疏學淺,如有錯誤不當之處,請批評指正,如有侵權,請立即聯繫我進行刪除。
如果能為您帶來一點點幫助,我將十分高興,也多謝您關注:hongmaolinux 和轉發推薦,謝謝!