blob: 7910fd77f4857ff15ad4dd86826c92e7ba0c1cf7 [file] [log] [blame]
"use strict";(self.webpackChunkdoris_website=self.webpackChunkdoris_website||[]).push([[26760],{15680:(e,n,t)=>{t.d(n,{xA:()=>g,yg:()=>m});var o=t(296540);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function r(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,o,a=function(e,n){if(null==e)return{};var t,o,a={},i=Object.keys(e);for(o=0;o<i.length;o++)t=i[o],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)t=i[o],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=o.createContext({}),p=function(e){var n=o.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},g=function(e){var n=p(e.components);return o.createElement(l.Provider,{value:n},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},d=o.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,g=s(e,["components","mdxType","originalType","parentName"]),c=p(t),d=a,m=c["".concat(l,".").concat(d)]||c[d]||u[d]||i;return t?o.createElement(m,r(r({ref:n},g),{},{components:t})):o.createElement(m,r({ref:n},g))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,r=new Array(i);r[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[c]="string"==typeof e?e:a,r[1]=s;for(var p=2;p<i;p++)r[p]=t[p];return o.createElement.apply(null,r)}return o.createElement.apply(null,t)}d.displayName="MDXCreateElement"},744871:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var o=t(58168),a=(t(296540),t(15680));const i={title:"Configuring Doris Cluster",language:"en"},r=void 0,s={unversionedId:"install/cluster-deployment/k8s-deploy/install-config-cluster",id:"version-2.0/install/cluster-deployment/k8s-deploy/install-config-cluster",title:"Configuring Doris Cluster",description:"\x3c!--",source:"@site/versioned_docs/version-2.0/install/cluster-deployment/k8s-deploy/install-config-cluster.md",sourceDirName:"install/cluster-deployment/k8s-deploy",slug:"/install/cluster-deployment/k8s-deploy/install-config-cluster",permalink:"/docs/2.0/install/cluster-deployment/k8s-deploy/install-config-cluster",draft:!1,tags:[],version:"2.0",frontMatter:{title:"Configuring Doris Cluster",language:"en"},sidebar:"docs",previous:{title:"Deploying Doris Operator",permalink:"/docs/2.0/install/cluster-deployment/k8s-deploy/install-operator"},next:{title:"Deploying Doris Cluster",permalink:"/docs/2.0/install/cluster-deployment/k8s-deploy/install-doris-cluster"}},l={},p=[{value:"Configuration data and persistent storage",id:"configuration-data-and-persistent-storage",level:2},{value:"Persistence directory type",id:"persistence-directory-type",level:3},{value:"Data persistence to network PV",id:"data-persistence-to-network-pv",level:3},{value:"Cluster deployment configuration",id:"cluster-deployment-configuration",level:2},{value:"Cluster name",id:"cluster-name",level:3},{value:"Mirror version",id:"mirror-version",level:3},{value:"Cluster topology",id:"cluster-topology",level:3},{value:"Service configuration",id:"service-configuration",level:3},{value:"Cluster parameter configuration",id:"cluster-parameter-configuration",level:2},{value:"FE ConfigMap",id:"fe-configmap",level:3},{value:"BE ConfigMap",id:"be-configmap",level:3},{value:"Add external configuration files to the conf directory",id:"add-external-configuration-files-to-the-conf-directory",level:3},{value:"Configure multi-disk storage for BE",id:"configure-multi-disk-storage-for-be",level:3}],g={toc:p},c="wrapper";function u(e){let{components:n,...t}=e;return(0,a.yg)(c,(0,o.A)({},g,t,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("h2",{id:"configuration-data-and-persistent-storage"},"Configuration data and persistent storage"),(0,a.yg)("p",null,"In a Doris cluster, components including FE, BE, CN, and monitoring components all need to persist data to physical storage. Kubernetes provides ",(0,a.yg)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/"},"Persistent Volumes")," the ability to persist data to physical storage. In a Kubernetes environment, there are two main types of Persistent Volumes:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"Local PV storage (Local Persistent Volumes): Local PV is where Kubernetes directly uses the local disk directory of the host to persistently store container data. Local PV provides smaller network latency and can provide better read and write capabilities when using high-performance hard drives such as SSDs. Since the local PV is bound to the host, when the host fails, the local PV undergoes fault drift."),(0,a.yg)("li",{parentName:"ul"},"Network PV storage (Network Persistent Volumes): Network PV is a storage resource accessed through the network. The network PV can be accessed by any node in the cluster. When the host fails, the network PV can be mounted to other nodes and continued to be used.")),(0,a.yg)("p",null,"StorageClass can be used to define the type and behavior of PV. StorageClass can decouple disk resources from containers to achieve data persistence and reliability. In Doris Operator, deploying Doris on Kubernetes can support local PV and network PV, and you can choose according to business needs."),(0,a.yg)("admonition",{title:"Warning",type:"caution"},(0,a.yg)("p",{parentName:"admonition"},"It is recommended to persist data to storage at deployment time.\nIf PersistentVolumeClaim is not configured during deployment, Doris Operator will use emptyDir mode by default to store metadata, data, and logs. When the pod is restarted, related data will be lost.")),(0,a.yg)("h3",{id:"persistence-directory-type"},"Persistence directory type"),(0,a.yg)("p",null,"In Doris, the following directories are recommended for persistent storage:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"FE node: doris-meta, log"),(0,a.yg)("li",{parentName:"ul"},"BE node: storage, log"),(0,a.yg)("li",{parentName:"ul"},"CN node: storage, log"),(0,a.yg)("li",{parentName:"ul"},"Broker node: log")),(0,a.yg)("p",null,"There are multiple log types in Doris, such as INFO log, OUT log, GC log and audit log. Doris Operator can output logs to the console and the specified directory at the same time. If the user's Kubernetes has complete log collection capabilities, Doris' INFO logs can be collected through console output. It is recommended that all Doris logs be persisted to the designated storage through PVC configuration, which will help locate and troubleshoot problems."),(0,a.yg)("h3",{id:"data-persistence-to-network-pv"},"Data persistence to network PV"),(0,a.yg)("p",null,"Doris Operator uses Kubernetes' default StorageClass to support FE and BE storage. In the CR of DorisCluster, the specified network PV can be configured by modifying the StorageClass to specify ",(0,a.yg)("inlineCode",{parentName:"p"},"persistentVolumeClaimSpec.storageClassName"),"."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"persistentVolumes:\n - mountPath: /opt/apache-doris/fe/doris-meta\n name: storage0\n persistentVolumeClaimSpec:\n # When use specific storageclass, the storageClassName should reConfig, example as annotation.\n storageClassName: ${your_storageclass}\n accessModes:\n - ReadWriteOnce\n resources:\n # notice: if the storage size is less than 5G, fe will not start normal.\n requests:\n storage: 100Gi\n")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"FE configuration persistent storage")),(0,a.yg)("p",null,"When deploying a cluster, it is recommended to provide persistent storage for the doris-meta and log directories in FE. Doris-meta users store metadata, usually from a few hundred MB to dozens of GB. It is recommended to reserve 100GB. The log directory is used to store FE logs. It is generally recommended to reserve 50GB."),(0,a.yg)("p",null,"In the following example, FE uses StorageClass to mount metadata storage and log storage:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"feSpec:\n persistentVolumes:\n - name: fe-meta\n mountPath: /opt/apache-doris/fe/doris-meta\n persistentVolumeClaimSpec:\n storageClassName: ${storageClassName}\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n Storage: 50Gi\n - name: fe-log\n mountPath: /opt/apache-doris/fe/log\n persistentVolumeClaimSpec:\n storageClassName: ${storageClassName}\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Gi\n")),(0,a.yg)("p",null,"Among them, the name of ",(0,a.yg)("a",{parentName:"p",href:"https://kubernetes.io/docs/concepts/storage/storage-classes/"},"StorageClass")," needs to be specified in ${storageClassName}. You can use the following command to view the StorageClass supported in the current Kubernetes cluster:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-bash"},"kubectl get sc\n")),(0,a.yg)("p",null,"The return result is as follows:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-bash"},"NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE\nopenebs-hostpath openebs.io/local Delete WaitForFirstConsumer false 212d\nopenebs-device openebs.io/local Delete WaitForFirstConsumer false 212d\nopenebs-jiva-csi-default jiva.csi.openebs.io Delete Immediate true 212d\nlocal-storage kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 149d\nmicrok8s-hostpath (default) microk8s.io/hostpath Delete Immediate false 219d\ndoris-storage openebs.io/local Delete WaitForFirstConsumer false 54d\n")),(0,a.yg)("admonition",{title:"Tip",type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"The default metadata path and log path can be modified by configuring ",(0,a.yg)("a",{parentName:"p",href:"#FE%20ConfigMap"},"ConfigMap"),":"),(0,a.yg)("ol",{parentName:"admonition"},(0,a.yg)("li",{parentName:"ol"},"The mounthPath configuration of fe-meta needs to be consistent with the meta_dir variable configuration path in ConfigMap. By default, metadata will be written to the /opt/apache-doris/fe/doris-meta directory;"),(0,a.yg)("li",{parentName:"ol"},"The mounthPath configuration of fe-log needs to be consistent with the LOG_DIR variable path in ConfigMap. By default, log data will be written to the /opt/apache-doris/fe/log directory."))),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"BE configuration persistent storage")),(0,a.yg)("p",null,"When deploying a cluster, it is recommended that the storage and log directories in BE be used for persistent storage. Storage users store data, which needs to be measured based on the amount of business data. The log directory is used to store FE logs. It is generally recommended to reserve 50GB."),(0,a.yg)("p",null,"In the following example, BE uses StorageClass to mount the data storage and log storage:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"beSpec:\n persistentVolumes:\n - mountPath: /opt/apache-doris/be/storage\n name: be-storage\n persistentVolumeClaimSpec:\n storageClassName: {storageClassName}\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n Storage: 1Ti\n - mountPath: /opt/apache-doris/be/log\n name: belog\n persistentVolumeClaimSpec:\n storageClassName: {storageClassName}\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Gi\n")),(0,a.yg)("h2",{id:"cluster-deployment-configuration"},"Cluster deployment configuration"),(0,a.yg)("h3",{id:"cluster-name"},"Cluster name"),(0,a.yg)("p",null,"The cluster name can be configured by modifying metadata.name in DorisCluster Custom Resource."),(0,a.yg)("h3",{id:"mirror-version"},"Mirror version"),(0,a.yg)("p",null,"When deploying a Doris cluster, you can specify the cluster version. When deploying a cluster, you should ensure that the versions of each component in the cluster are consistent. Configure the version of each component by modifying ",(0,a.yg)("inlineCode",{parentName:"p"},"spec.{feSpec|beSpec}.image"),"."),(0,a.yg)("h3",{id:"cluster-topology"},"Cluster topology"),(0,a.yg)("p",null,"Before deploying a Doris cluster, you need to plan the topology of the cluster based on your business. The number of nodes of each component can be configured by modifying spec.{feSpec|beSpec}.replicas. Based on the principle of high data availability of production nodes, Doris Operator stipulates that there are at least 3 nodes in the Kubernetes cluster in the cluster. At the same time, in order to ensure the availability of the cluster, it is recommended to deploy at least 3 FE and BE nodes."),(0,a.yg)("h3",{id:"service-configuration"},"Service configuration"),(0,a.yg)("p",null,"Kubernetes provides different Serivce methods to expose Doris's external access interface, such as ",(0,a.yg)("inlineCode",{parentName:"p"},"ClusterIP"),", ",(0,a.yg)("inlineCode",{parentName:"p"},"NodePort"),", ",(0,a.yg)("inlineCode",{parentName:"p"},"LoadBalancer"),", etc."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"ClusterIP")),(0,a.yg)("p",null,"A service of type ClusterIP will create a virtual IP inside the cluster. It can only be accessed within the Kubernetes cluster through ClusterIP and is not visible to the outside world. In Doris Custom Resource, the ClusterIP type Service is used by default."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"NodePort")),(0,a.yg)("p",null,"Can be exposed via NodePort when LoadBalancer is not available. NodePort exposes services through the node's IP and static port. A NodePort service can be accessed from outside the cluster by requesting ",(0,a.yg)("inlineCode",{parentName:"p"},"NodeIP + NodePort"),"."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"...\nfeSpec:\n replicas: 3\n service:\n type: NodePort\n...\nbeSpec:\n replicas: 3\n service:\n type: NodePort\n...\n")),(0,a.yg)("h2",{id:"cluster-parameter-configuration"},"Cluster parameter configuration"),(0,a.yg)("p",null,"Doris uses ",(0,a.yg)("inlineCode",{parentName:"p"},"ConfigMap")," in Kubernetes to decouple configuration files and services. All nodes of the Doris component use ConfigMap as unified configuration management in Kubernetes, and all nodes of the component are started with the same configuration information. Doris' system parameters are stored in ConfigMap using key-value pairs. When deploying a doris cluster, you need to deploy ConfigMap under the same namespace in advance."),(0,a.yg)("p",null,"In the CR of Doris Cluster, provide ConfigMapInfo definitions to mount configuration information for each component. ConfigMapInfo contains two variables:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"ConfigMapName represents the name of the ConfigMap you want to use"),(0,a.yg)("li",{parentName:"ul"},"ResolveKey represents the corresponding configuration file, select fe.conf for FE configuration, and be.conf for BE configuration.")),(0,a.yg)("h3",{id:"fe-configmap"},"FE ConfigMap"),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Definition FE ConfigMap")),(0,a.yg)("p",null,"When using ConfigMap to define FE configuration, you need to first define and deliver ConfigMap to the Kubernetes cluster."),(0,a.yg)("p",null,"The following example defines a ConfigMap named fe-conf:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: fe-conf\n labels:\n app.kubernetes.io/component: fe\ndata:\n fe.conf: |\n CUR_DATE=`date +%Y%m%d-%H%M%S`\n\n # the output dir of stderr and stdout\n LOG_DIR = ${DORIS_HOME}/log\n\n JAVA_OPTS="-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx8192m -XX:+UseMembar -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=7 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -Xloggc:$DORIS_HOME/log/fe.gc.log.$CUR_DATE"\n\n # For jdk 9+, this JAVA_OPTS will be used as default JVM options\n JAVA_OPTS_FOR_JDK_9="-Djavax.security.auth.useSubjectCredsOnly=false -Xss4m -Xmx8192m -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=7 -XX:+CMSClassUnloadingEnabled -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -Xlog:gc*:$DORIS_HOME/log/fe.gc.log.$CUR_DATE:time"\n\n # INFO, WARN, ERROR, FATAL\n sys_log_level = INFO\n\n # NORMAL, BRIEF, ASYNC\n sys_log_mode = NORMAL\n\n # Default dirs to put jdbc drivers,default value is ${DORIS_HOME}/jdbc_drivers\n # jdbc_drivers_dir = ${DORIS_HOME}/jdbc_drivers\n\n http_port = 8030\n rpc_port = 9020\n query_port = 9030\n edit_log_port = 9010\n')),(0,a.yg)("p",null,"Among them, the name of FE ConfigMap is defined in metadata.name, and the database configuration in fe.conf is defined in data."),(0,a.yg)("admonition",{title:"Tip",type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"Use the data field in ConfigMap to store key-value pairs. In the above FE ConfigMap:"),(0,a.yg)("ul",{parentName:"admonition"},(0,a.yg)("li",{parentName:"ul"},"fe.conf is the key in the key-value pair, using ",(0,a.yg)("inlineCode",{parentName:"li"},"|")," means that newlines and indents in subsequent strings will be preserved"),(0,a.yg)("li",{parentName:"ul"},"Subsequent configuration is the value in the key-value pair, which is the same as the configuration in the fe.conf file\nIn the data field, due to the use of the ",(0,a.yg)("inlineCode",{parentName:"li"},"|")," symbol to retain the subsequent string format, two spaces need to be maintained in subsequent configurations."))),(0,a.yg)("p",null,"After defining the FE ConfigMap, you need to issue it through the ",(0,a.yg)("inlineCode",{parentName:"p"},"kubectl apply")," command."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Using FE ConfigMap")),(0,a.yg)("p",null,"If you need to use FE ConfigMap, you need to specify the defined ConfigMap through spec.feSpec.configMapInfo in the RC of Doris Cluster."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"Kind: DorisCluster\nmetadata:\n name: doriscluster-sample-configmap\nspec:\n feSpec:\n configMapInfo:\n configMapName: {feConfigMapName}\n resolveKey: fe.conf\n...\n")),(0,a.yg)("p",null,"Replace ${feConfigMapName} with fe-conf in the above example to use the FE ConfigMap defined in the above example. For FE ConfigMap, you need to keep the resolveKey field fixed to ",(0,a.yg)("inlineCode",{parentName:"p"},"fe.conf"),"."),(0,a.yg)("h3",{id:"be-configmap"},"BE ConfigMap"),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Definition BE ConfigMap")),(0,a.yg)("p",null,"When using ConfigMap to define BE configuration, you need to first define and deliver ConfigMap to the Kubernetes cluster."),(0,a.yg)("p",null,"The following example defines a ConfigMap named be-conf:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: be-conf\n labels:\n app.kubernetes.io/component: be\ndata:\n be.conf: |\n CUR_DATE=`date +%Y%m%d-%H%M%S`\n\n PPROF_TMPDIR="$DORIS_HOME/log/"\n\n JAVA_OPTS="-Xmx1024m -DlogPath=$DORIS_HOME/log/jni.log -Xloggc:$DORIS_HOME/log/be.gc.log.$CUR_DATE -Djavax.security.auth.useSubjectCredsOnly=false -Dsun.java.command=DorisBE -XX:-CriticalJNINatives -DJDBC_MIN_POOL=1 -DJDBC_MAX_POOL=100 -DJDBC_MAX_IDLE_TIME=300000 -DJDBC_MAX_WAIT_TIME=5000"\n\n # For jdk 9+, this JAVA_OPTS will be used as default JVM options\n JAVA_OPTS_FOR_JDK_9="-Xmx1024m -DlogPath=$DORIS_HOME/log/jni.log -Xlog:gc:$DORIS_HOME/log/be.gc.log.$CUR_DATE -Djavax.security.auth.useSubjectCredsOnly=false -Dsun.java.command =DorisBE -XX:-CriticalJNINatives -DJDBC_MIN_POOL=1 -DJDBC_MAX_POOL=100 -DJDBC_MAX_IDLE_TIME=300000 -DJDBC_MAX_WAIT_TIME=5000"\n\n # since 1.2, the JAVA_HOME need to be set to run BE process.\n # JAVA_HOME=/path/to/jdk/\n\n # https://github.com/apache/doris/blob/master/docs/zh-CN/community/developer-guide/debug-tool.md#jemalloc-heap-profile\n # https://jemalloc.net/jemalloc.3.html\n JEMALLOC_CONF="percpu_arena:percpu,background_thread:true,metadata_thp:auto,muzzy_decay_ms:15000,dirty_decay_ms:15000,oversize_threshold:0,lg_tcache_max:20,prof:false,lg_prof_interval:32,lg_prof_sample:19,prof_gd ump:false,prof_accum:false ,prof_leak:false,prof_final:false"\n JEMALLOC_PROF_PRFIX=""\n\n # INFO, WARNING, ERROR, FATAL\n sys_log_level = INFO\n\n # ports for admin, web, heartbeat service\n be_port = 9060\n webserver_port = 8040\n heartbeat_service_port = 9050\n brpc_port = 8060\n')),(0,a.yg)("p",null,"Among them, the name of BE ConfigMap is defined in metadata.name, and the database configuration in be.conf is defined in data."),(0,a.yg)("admonition",{title:"Tip",type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"Use the data field in ConfigMap to store key-value pairs. In the above BE ConfigMap:"),(0,a.yg)("ul",{parentName:"admonition"},(0,a.yg)("li",{parentName:"ul"},"be.conf is the key in the key-value pair, using ",(0,a.yg)("inlineCode",{parentName:"li"},"|")," means that newlines and indents in subsequent strings will be retained"),(0,a.yg)("li",{parentName:"ul"},"Subsequent configuration is the value in the key-value pair, which is the same as the configuration in the be.conf file\nIn the data field, due to the use of the ",(0,a.yg)("inlineCode",{parentName:"li"},"|")," symbol to retain the subsequent string format, two spaces need to be maintained in subsequent configurations."))),(0,a.yg)("p",null,"After defining BE ConfigMap, you need to issue it through the ",(0,a.yg)("inlineCode",{parentName:"p"},"kubectl apply")," command."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Using BE ConfigMap")),(0,a.yg)("p",null,"If you need to use BE ConfigMap, you need to specify the defined ConfigMap through spec.beSpec.configMapInfo in the RC of Doris Cluster."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"Kind: DorisCluster\nmetadata:\n name: doriscluster-sample-configmap\nspec:\n beSpec:\n configMapInfo:\n configMapName: {beConfigMapName}\n resolveKey: be.conf\n...\n")),(0,a.yg)("p",null,"Replace ${beConfigMapName} with be-conf in the above example to use the BE ConfigMap defined in the above example. For BE ConfigMap, you need to keep the resolveKey field fixed to ",(0,a.yg)("inlineCode",{parentName:"p"},"be.conf"),"."),(0,a.yg)("h3",{id:"add-external-configuration-files-to-the-conf-directory"},"Add external configuration files to the conf directory"),(0,a.yg)("p",null,"When using the Catalog function to access external data sources, you need to add the relevant configuration files to the conf directory of the Doris node. For example, when accessing the hive catalog, you need to add core-site.xml, hdfs-site.xml and hive-site.xml The files are placed in the conf directories of FE and BE."),(0,a.yg)("p",null,"In the Kubernetes environment, the relevant configuration files of the catalog need to be loaded into Doris in the form of ConfigMap. The following example shows loading the core-site.xml file into BE:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: be-configmap\n labels:\n app.kubernetes.io/component: be\ndata:\n be.conf: |\n be_port = 9060\n webserver_port = 8040\n heartbeat_service_port = 9050\n brpc_port = 8060\n core-site.xml: |\n <?xml version="1.0" encoding="UTF-8"?>\n <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>\n <configuration>\n <property>\n <name>hadoop.security.authentication</name>\n <value>kerberos</value>\n </property>\n </configuration>\n ...\n')),(0,a.yg)("p",null,"Among them, the configured key-value pairs are stored in the data field. In the above example, the key-value pairs whose keys are be.conf and core-site.xml are stored."),(0,a.yg)("p",null,"In the data field, the following key-value structure mapping needs to be satisfied:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"data:\n filename_1: |\n config_string\n filename_2: |\n config_string\n filename_3: |\n config_string\n")),(0,a.yg)("h3",{id:"configure-multi-disk-storage-for-be"},"Configure multi-disk storage for BE"),(0,a.yg)("p",null,"Doris supports mounting multiple PVs for BE. By configuring the BE parameter ",(0,a.yg)("inlineCode",{parentName:"p"},"storage_root_path"),", you can specify BE to use multi-disk storage. In the Kubernetes environment, you can map pv in DorisCluster CR and configure the ",(0,a.yg)("inlineCode",{parentName:"p"},"storage_root_path")," parameter for BE through ConfigMap."),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Configure pv mapping for BE multi-disk storage")),(0,a.yg)("p",null,"In the DorisCluster CR file, compared to the single-disk configuration, you need to add the descriptions of ",(0,a.yg)("inlineCode",{parentName:"p"},"configMapInfo")," and ",(0,a.yg)("inlineCode",{parentName:"p"},"persistentVolumeClaimSpec"),":"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"The specified ConfigMap under the same namespace can be identified through ",(0,a.yg)("inlineCode",{parentName:"li"},"configMapInfo")," configuration, and the resolveKey is fixed to be.conf"),(0,a.yg)("li",{parentName:"ul"},"Multiple pv mappings can be configured for the BE storage directory through ",(0,a.yg)("inlineCode",{parentName:"li"},"persistentVolumeClaimSpec"))),(0,a.yg)("p",null,"In the following example, the pv mapping of two disks is configured for BE:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},"...\n beSpec:\n replicas: 3\n image: selectdb/doris.be-ubuntu:2.0.2\n limits:\n cpu: 8\n memory: 16Gi\n requests:\n cpu: 8\n memory: 16Gi\n configMapInfo:\n configMapName: be-configmap\n resolveKey: be.conf\n persistentVolumes:\n - mountPath: /opt/apache-doris/be/storage1\n name: storage2\n persistentVolumeClaimSpec:\n # when use specific storageclass, the storageClassName should reConfig, example as annotation.\n #storageClassName: openebs-jiva-csi-default\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Gi\n - mountPath: /opt/apache-doris/be/storage2\n name: storage3\n persistentVolumeClaimSpec:\n # when use specific storageclass, the storageClassName should reConfig, example as annotation.\n #storageClassName: openebs-jiva-csi-default\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Gi\n - mountPath: /opt/apache-doris/be/log\n name: storage4\n persistentVolumeClaimSpec:\n # when use specific storageclass, the storageClassName should reConfig, example as annotation.\n #storageClassName: openebs-jiva-csi-default\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Gi\n")),(0,a.yg)("p",null,"In the above example, the Doris cluster specifies multi-disk storage"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},"beSpec.persistentVolumes specifies multiple pvs in an array, mapping two data storage pvs in ",(0,a.yg)("inlineCode",{parentName:"li"},"/opt/apache-doris/be/storage{1,2}")),(0,a.yg)("li",{parentName:"ul"},"beSpec.configMapInfo specifies that the ConfigMap named ",(0,a.yg)("inlineCode",{parentName:"li"},"be-configmap")," needs to be mounted")),(0,a.yg)("p",null,(0,a.yg)("strong",{parentName:"p"},"Configure BE ConfigMap to specify the storage_root_path parameter")),(0,a.yg)("p",null,"According to the BE ConfigMap name specified in DorisCluster CR, you need to create the corresponding ConfigMap and specify the storage_root_path parameter."),(0,a.yg)("p",null,"In the following example, the ",(0,a.yg)("inlineCode",{parentName:"p"},"storage_root_path")," parameter is specified in the ConfigMap named ",(0,a.yg)("inlineCode",{parentName:"p"},"be-configmap")," to use two disks:"),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-yaml"},'apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: be-configmap\n labels:\n app.kubernetes.io/component: be\ndata:\n be.conf: |\n CUR_DATE=`date +%Y%m%d-%H%M%S`\n\n PPROF_TMPDIR="$DORIS_HOME/log/"\n\n JAVA_OPTS="-Xmx1024m -DlogPath=$DORIS_HOME/log/jni.log -Xloggc:$DORIS_HOME/log/be.gc.log.$CUR_DATE -Djavax.security.auth.useSubjectCredsOnly=false -Dsun.java.command=DorisBE -XX:-CriticalJNINatives -DJDBC_MIN_POOL=1 -DJDBC_MAX_POOL=100 -DJDBC_MAX_IDLE_TIME=300000 -DJDBC_MAX_WAIT_TIME=5000"\n\n # For jdk 9+, this JAVA_OPTS will be used as default JVM options\n JAVA_OPTS_FOR_JDK_9="-Xmx1024m -DlogPath=$DORIS_HOME/log/jni.log -Xlog:gc:$DORIS_HOME/log/be.gc.log.$CUR_DATE -Djavax.security.auth.useSubjectCredsOnly=false -Dsun.java.command =DorisBE -XX:-CriticalJNINatives -DJDBC_MIN_POOL=1 -DJDBC_MAX_POOL=100 -DJDBC_MAX_IDLE_TIME=300000 -DJDBC_MAX_WAIT_TIME=5000"\n\n # since 1.2, the JAVA_HOME need to be set to run BE process.\n # JAVA_HOME=/path/to/jdk/\n\n # https://github.com/apache/doris/blob/master/docs/zh-CN/community/developer-guide/debug-tool.md#jemalloc-heap-profile\n # https://jemalloc.net/jemalloc.3.html\n JEMALLOC_CONF="percpu_arena:percpu,background_thread:true,metadata_thp:auto,muzzy_decay_ms:15000,dirty_decay_ms:15000,oversize_threshold:0,lg_tcache_max:20,prof:false,lg_prof_interval:32,lg_prof_sample:19,prof_gd ump:false,prof_accum:false ,prof_leak:false,prof_final:false"\n JEMALLOC_PROF_PRFIX=""\n\n # INFO, WARNING, ERROR, FATAL\n sys_log_level = INFO\n\n # ports for admin, web, heartbeat service\n be_port = 9060\n webserver_port = 8040\n heartbeat_service_port = 9050\n brpc_port = 8060\n \n storage_root_path = /opt/apache-doris/be/storage,medium:ssd;/opt/apache-doris/be/storage1,medium:ssd\n')),(0,a.yg)("admonition",{title:"Warning",type:"caution"},(0,a.yg)("p",{parentName:"admonition"},"When creating a BE ConfigMap, you need to pay attention to the following:"),(0,a.yg)("ol",{parentName:"admonition"},(0,a.yg)("li",{parentName:"ol"},"metadata.name needs to be the same as beSpec.configMapInfo.configMapName in DorisCluster CR, indicating that the cluster uses the specified ConfigMap;"),(0,a.yg)("li",{parentName:"ol"},"The storage_root_path parameter in ConfigMap must correspond one-to-one with the persistentVolume data disk in DorisCluster CR."))))}u.isMDXComponent=!0}}]);