doris部署安装及运维相关记录
本记录内容目前包括:
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'
或者如下(&表示后台运行):
sh /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,直至错误提示消失。