本記錄內容目前包括:
3、解決httpclient方式向doris導入數據時,“no valid Basic authorization”的錯誤
4、be節點無法連接fe,提示:java.net.NoRouteToHostException: 沒有到主機的路由
————————————————————————————————————————————————————————————————————————————————————————
1、doris部署安裝:(直接參考doris官網也很清晰~)
建議先把要部署的各個服務器的防火牆關閉(避免在部署過程中fe與be之間的正常通訊被限制):systemctl disable firewalld.service
FE的部署:
a、服務器安裝jdk;
yum install java-1.8.0-openjdk
b、將從官網下載的編譯好的fe目錄上傳到服務器;
c、修改配置文件 /conf/fe.conf
主要是各端口號跟本機的ip地址,如果使用默認端口號的話,則只需要修改ip為本機實際地址即可:
http_port = 8030
rpc_port = 9020
query_port = 9030
edit_log_port = 9010
priority_networks = 172.17.11.2/24
d:啟動fe服務
進入 /fe/bin目錄,執行 sh start_fe.sh
BE的部署:
a、設置系統最大打開文件句柄數
修改配置文件 vi /etc/security/limits.conf
增加下面兩行:
* soft nofile 65536
* hard nofile 65536
b、關閉交換分區、及設置vm.max_map_count大小
swapoff -a
修改配置文件 vi /etc/fstab
將 /dev/mapper/centos_centos7-swap swap swap defaults 0 0 這一行使用#注釋掉
執行 free -m 確認swap已經關閉。如果Swap那一行全部為0則表示已經關閉了。
修改配置文件 vi /etc/sysctl.conf 使得修改永久起效
增加下面2行:
vm.swappiness=0
vm.max_map_count=2000000
執行命令使得配置生效 sysctl -p
c、服務器安裝jdk
yum install java-1.8.0-openjdk
d、將從官網下載編譯好的be目錄上傳至服務器,修改conf目錄中的配置文件
vi be.conf
默認配置,修改其中的ip地址與數據存放位置即可,其他一般不用改。
be_port = 9060
be_rpc_port = 9070
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
priority_networks = 172.17.11.11/24
storage_root_path = /data
e、啟動be服務:進入/be/bin 目錄,執行
sh start_be.sh --daemon
f、將新的be節點加入集群
通過mysql客戶端連接到fe節點: mysql -P 9030 -h 172.17.11.2 -u root -p
執行添加節點命令:ALTER SYSTEM ADD BACKEND "172.17.11.11:9050";
此時,正常情況下,在doris的管理頁面中,就可以看到新的be節點了:
————————————————————————————————————————————————————————————————————————————————————————
修改centos的啟動控制腳本文件,將執行命令行加入腳本
vi /etc/rc.d/rc.local
以啟動be服務為例:
su - root -c '/home/be/bin/start_be.sh --daemon'
保存后,將腳本文件的權限賦上。centos7以上版本默認沒有權限。
chmod +x /etc/rc.d/rc.local
在sh命令文件所在目錄執行 chmod u+x *.sh
————————————————————————————————————————————————————————————————————————————————————————
3、解決httpclient方式向doris導入數據時,“no valid Basic authorization”的錯誤:
導入核心代碼(以下代碼為出錯代碼):
url = $"{url}{Dbname}/{Table}/_stream_load";
byte[] postData = Encoding.UTF8.GetBytes(JsonDatas);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "PUT";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.ContentType = "application/json;charset=UTF-8";
request.UserAgent = "Mozilla/4.0 (compatible;MSIE 6.0;)";
request.ContentLength = postData.Length;
request.Timeout = 60000;
request.Headers.Add("expect", "100-continue");
request.Headers.Add("format", "json");
request.Headers.Add("strip_outer_array", "true");
request.Headers.Add("jsonpaths", jsonpaths);
request.Headers.Add("label", DealLabe);
request.PreAuthenticate = true;
NetworkCredential nc = new NetworkCredential(username, password);
request.Credentials = nc;
System.IO.Stream outputStream = request.GetRequestStream();
outputStream.Write(postData, 0, postData.Length);
outputStream.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
ResultStr = reader.ReadToEnd();
reader.Close();
錯誤提示:
該錯誤出現的原因在於,訪問doris的fe時,fe需要重定向到一個特定的be,在重定向的過程中,同樣需要進行身份驗證。而上述寫法會讓fe自己重定向,這個過程中,fe並沒有將傳入的身份驗證信息傳遞到be,導致報錯。
解決方案1:就是我們自己去處理一下,具體代碼如下(注意 request.AllowAutoRedirect = false;這樣可以避免doris直接重定向。相當於是我們自己訪問兩次,第一次訪問fe的url,獲取分配的be的url;第二次再訪問be的url即可。)
解決方案2:直接訪問be節點,更省事:P(如從配置好可用的數個be url中,隨機選擇1個作為插入url,如果失敗則隨機選擇另1個)
public static string PutJsonToDris(string JsonDatas, string url, string Dbname, string Table, string jsonpaths, string DealLabe, string username, string password)
{
string ResultStr = "";
try
{
byte[] postData = Encoding.UTF8.GetBytes(JsonDatas);
url = $"{url}{Dbname}/{Table}/_stream_load";
HttpWebRequest request = BuildRequest(url, postData, jsonpaths, DealLabe, username, password);
HttpWebResponse httpRes = (HttpWebResponse)request.GetResponse();
if (httpRes.StatusCode == HttpStatusCode.RedirectKeepVerb)
{
//如果返回307重定向,則獲取重定向的網址(正常情況下,訪問doris的fe,fe會返回一個可用的be地址,我們需要用返回的這個be地址重新訪問一次)
url = httpRes.Headers["Location"];
request = BuildRequest(url, postData, jsonpaths, DealLabe, username, password);
// 提交請求數據
System.IO.Stream outputStream = request.GetRequestStream();
outputStream.Write(postData, 0, postData.Length);
outputStream.Close();
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8"));
ResultStr = reader.ReadToEnd();
reader.Close();
}
httpRes.Close();
}
catch (SystemException ee)
{
ResultStr = $"\"Status\":\"SysError\",\"Message\":\"{ee.Message}\",\"StackTrace\":\"{ee.StackTrace}\"";
}
return ResultStr;
}
private static HttpWebRequest BuildRequest(string url, byte[] postData, string jsonpaths, string DealLabe, string username, string password)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
request.Method = "PUT";
request.ContentType = "application/json;charset=UTF-8";
request.UserAgent = "Mozilla/4.0 (compatible;MSIE 6.0;)";
request.ContentLength = postData.Length;
request.Headers.Add("expect", "100-continue");
request.Headers.Add("format", "json");
request.Headers.Add("strip_outer_array", "true");
request.Headers.Add("jsonpaths", jsonpaths);
request.Headers.Add("label", DealLabe);
request.PreAuthenticate = true;
string usernamePassword = username + ":" + password;
CredentialCache mycache = new CredentialCache();
mycache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
request.Credentials = mycache;
request.Headers.Add("Authorization", "Basic " + (Convert.ToBase64String(Encoding.UTF8.GetBytes(usernamePassword))).Cof_FilterUnVisible());
return request;
}
————————————————————————————————————————————————————————————————————————————————————————
4、be節點無法連接fe,提示:java.net.NoRouteToHostException: 沒有到主機的路由
安裝部署doris,be節點一直無法收到fe心跳,提示:“waiting to receive first heartbeat from frontend”;從fe節點的管理界面里看,be節點的錯誤信息為:“java.net.NoRouteToHostException”。這種情況很可能是be節點防火牆開啟且沒有放行對應的doris端口號。
解決方案:可以直接關閉防火牆,或者放行doris的對應端口號。
————————————————————————————————————————————————————————————————————————————————————————
doris1.2版本下載的文件為xxx.tar.xz,無法使用tar命令直接解包。
解決方案:先 xz -d xxx.tar.xz 將 xxx.tar.xz解壓成 xxx.tar 然后,再用 tar xvf xxx.tar來解包。
————————————————————————————————————————————————————————————————————————————————————————
某生產環境5台機器,1台fe、4台be,故障現象:使用navicat工具無法鏈接訪問doris數據庫、應用系統中也無法訪問doris數據庫。但是doris的管理界面能登陸進去,顯示各個節點狀態正常但看日志有錯誤;且后台往doris的be節點里寫數據(stream load模式,直接訪問be節點)的程序一直運行正常,doris能正常接收數據。
解決方案:重啟fe服務后故障消除,這算是doris的bug了。doris是通過fe節點對外提供查詢訪問的服務,故fe故障后,應用系統便無法訪問doris了。
————————————————————————————————————————————————————————————————————————————————————————
7、修復Unhealthy Tablets (doris版本:0.14)
現象:應用系統在查詢doris數據的時候,報錯。現場人員反饋原因為服務器異常斷電導致。
解決:
a、登錄doris后台管理界面,在statistic里查看健康情況,一看果然有不健康的數據分片。
b、mysql客戶端登錄fe節點:
show tablet xxxxx查看不健康分片情況:
執行detailCmd中的命令,進一步查看詳情:
SHOW PROC '/dbs/13726/1158185/partitions/1158092/1158186/1164288';
從紅框中可以看見,第三個be節點的數據分片是有問題的(正常來說,LstFailedVersion = -1,不等於-1說明有錯誤。LstFailedTime也不為空,時間正好是服務器斷電之后,說明該錯誤應該是服務器掉電造成的)。比較幸運的是,3個副本中2個是好的,可以利用doris自動恢復。
手工將錯誤分片的status狀態置為bad,讓doris自動從其他好的副本中恢復數據:
ADMIN SET REPLICA STATUS PROPERTIES("tablet_id" = "1164288", "backend_id" = "793238", "status" = "bad");
一段時間后再看,Unhealthy Tablets已經全部修復~
有時修復完成后,應用端仍報錯誤,則可以依次將提示的tablet的status狀態置為bad,直至錯誤提示消失。