組建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作業系統,但內部庫還是有些不一樣的地方。

對應的解決方法有如下幾種:

  1. 在 B 的環境中,直接進行 redis 源碼編譯,生成的可執行文件能在 B 中成功運行。
  2. 可以找到與 B 一樣的 strings /lib64/libc.so.6 |grep GLIBC_ 的作業系統環境,在其上編譯之後,直接將可執行文件拷貝到B上運行。
  3. 升級 B 伺服器的 GLIBC。
  4. 可在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 和轉發推薦,謝謝!

image