組建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相關知識。

參考鏈接:

https://blog.csdn.net/Jin_Kwok/article/details/80319441?utm_source=blogxgwz7

https://blog.csdn.net/weixin_34294649/article/details/91699158

本人才疏學淺,如有錯誤不當之處,請批評指正,如有侵權,請立即聯系我進行刪除。
如果能為您帶來一點點幫助,我將十分高興,也多謝您關注:hongmaolinux 和轉發推薦,謝謝!

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM