diff --git a/charts/gie-standalone/templates/_helpers.tpl b/charts/gie-standalone/templates/_helpers.tpl index 964cf43776c1..5721e99371ec 100644 --- a/charts/gie-standalone/templates/_helpers.tpl +++ b/charts/gie-standalone/templates/_helpers.tpl @@ -31,10 +31,6 @@ If release name contains chart name it will be used as a full name. {{- printf "%s-%s" (include "graphscope-store.fullname" .) "frontend" | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "graphscope-store.ingestor.fullname" -}} -{{- printf "%s-%s" (include "graphscope-store.fullname" .) "ingestor" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - {{- define "graphscope-store.store.fullname" -}} {{- printf "%s-%s" (include "graphscope-store.fullname" .) "store" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/charts/graphscope-store-one-pod/templates/_helpers.tpl b/charts/graphscope-store-one-pod/templates/_helpers.tpl index 6d8f336e5254..e20156e01358 100644 --- a/charts/graphscope-store-one-pod/templates/_helpers.tpl +++ b/charts/graphscope-store-one-pod/templates/_helpers.tpl @@ -31,10 +31,6 @@ If release name contains chart name it will be used as a full name. {{- printf "%s-%s" (include "graphscope-store.fullname" .) "frontend" | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "graphscope-store.ingestor.fullname" -}} -{{- printf "%s-%s" (include "graphscope-store.fullname" .) "ingestor" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - {{- define "graphscope-store.store.fullname" -}} {{- printf "%s-%s" (include "graphscope-store.fullname" .) "store" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/charts/graphscope-store-one-pod/templates/configmap.yaml b/charts/graphscope-store-one-pod/templates/configmap.yaml index 5bc4310f5826..5780ea54e8bf 100644 --- a/charts/graphscope-store-one-pod/templates/configmap.yaml +++ b/charts/graphscope-store-one-pod/templates/configmap.yaml @@ -21,9 +21,7 @@ data: rpc.max.bytes.mb={{ .Values.rpcMaxBytesMb }} store.node.count={{ .Values.store.replicaCount }} frontend.node.count=1 - ingestor.node.count={{ .Values.ingestor.replicaCount }} coordinator.node.count=1 - ingestor.queue.count={{ .Values.ingestor.replicaCount }} partition.count={{ .Values.store.replicaCount | mul 16 }} discovery.mode=zookeeper @@ -31,11 +29,6 @@ data: frontend.server.num=1 enable.hash.generate.eid={{ .Values.enableHashGenerateEid }} - ## Ingestor Config - ingestor.queue.buffer.max.count={{ .Values.ingestorQueueBufferMaxCount }} - ingestor.sender.buffer.max.count={{ .Values.ingestorSenderBufferMaxCount }} - ingestor.sender.operation.max.count={{ .Values.ingestorSenderOperationMaxCount }} - ## Coordinator Config snapshot.increase.interval.ms={{ .Values.snapshotIncreaseIntervalMs }} offsets.persist.interval.ms={{ .Values.offsetsPersistIntervalMs }} @@ -53,7 +46,6 @@ data: neo4j.bolt.server.disabled=true dns.name.prefix.frontend=localhost - dns.name.prefix.ingestor=localhost dns.name.prefix.coordinator=localhost dns.name.prefix.store=localhost diff --git a/charts/graphscope-store-one-pod/values.yaml b/charts/graphscope-store-one-pod/values.yaml index 119ffd133500..6ff2a4bee0dd 100644 --- a/charts/graphscope-store-one-pod/values.yaml +++ b/charts/graphscope-store-one-pod/values.yaml @@ -122,36 +122,6 @@ frontend: ## annotations: {} -ingestor: - replicaCount: 2 - - ## @param hostAliases pods host aliases - ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ - ## - hostAliases: [] - ## @param hostNetwork Specify if host network should be enabled for pods - ## - hostNetwork: false - ## @param hostIPC Specify if host IPC should be enabled for pods - ## - hostIPC: false - ## @param podLabels Extra labels for pods - ## Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - ## - podLabels: {} - ## @param podAnnotations Extra annotations for pods - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ - ## - podAnnotations: {} - ## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` - ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity - ## - - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - schedulerName: "" - - ## @section Common parameters ## @@ -350,11 +320,6 @@ javaOpts: "" rpcMaxBytesMb: 20 -## Ingestor Config -ingestorQueueBufferMaxCount: 102400 -ingestorSenderBufferMaxCount: 102400 -ingestorSenderOperationMaxCount: 102400 - ## Coordinator Config snapshotIncreaseIntervalMs: 1000 offsetsPersistIntervalMs: 3000 diff --git a/charts/graphscope-store/README.md b/charts/graphscope-store/README.md index 58d47b6f2330..d01b06862e4a 100644 --- a/charts/graphscope-store/README.md +++ b/charts/graphscope-store/README.md @@ -99,7 +99,6 @@ Here we give a list of most frequently used parameters. | store.replicaCount | Number of nodes | 2 | | frontend.replicaCount | Number of nodes | 1 | | frontend.service.type| Kubernetes Service type| NodePort | -| ingestor.replicaCount | Number of nodes | 1 | | coordinator.replicaCount | Number of nodes | 1 | ### Kafka chart parameters diff --git a/charts/graphscope-store/templates/_helpers.tpl b/charts/graphscope-store/templates/_helpers.tpl index d7af02d47e5b..5d4979c7d921 100644 --- a/charts/graphscope-store/templates/_helpers.tpl +++ b/charts/graphscope-store/templates/_helpers.tpl @@ -31,10 +31,6 @@ If release name contains chart name it will be used as a full name. {{- printf "%s-%s" (include "graphscope-store.fullname" .) "frontend" | trunc 63 | trimSuffix "-" -}} {{- end -}} -{{- define "graphscope-store.ingestor.fullname" -}} -{{- printf "%s-%s" (include "graphscope-store.fullname" .) "ingestor" | trunc 63 | trimSuffix "-" -}} -{{- end -}} - {{- define "graphscope-store.store.fullname" -}} {{- printf "%s-%s" (include "graphscope-store.fullname" .) "store" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/charts/graphscope-store/templates/configmap.yaml b/charts/graphscope-store/templates/configmap.yaml index 6d1351c462a7..29e3f84a4fd9 100644 --- a/charts/graphscope-store/templates/configmap.yaml +++ b/charts/graphscope-store/templates/configmap.yaml @@ -21,9 +21,7 @@ data: rpc.max.bytes.mb={{ .Values.rpcMaxBytesMb }} store.node.count={{ .Values.store.replicaCount }} frontend.node.count={{ .Values.frontend.replicaCount }} - ingestor.node.count={{ .Values.ingestor.replicaCount }} coordinator.node.count={{ .Values.coordinator.replicaCount }} - ingestor.queue.count={{ .Values.ingestor.replicaCount }} partition.count={{ .Values.store.replicaCount | mul 16 }} discovery.mode={{ .Values.discoveryMode }} @@ -33,11 +31,6 @@ data: frontend.server.num={{ .Values.frontend.replicaCount }} enable.hash.generate.eid={{ .Values.enableHashGenerateEid }} - ## Ingestor Config - ingestor.queue.buffer.max.count={{ .Values.ingestorQueueBufferMaxCount }} - ingestor.sender.buffer.max.count={{ .Values.ingestorSenderBufferMaxCount }} - ingestor.sender.operation.max.count={{ .Values.ingestorSenderOperationMaxCount }} - ## Coordinator Config snapshot.increase.interval.ms={{ .Values.snapshotIncreaseIntervalMs }} offsets.persist.interval.ms={{ .Values.offsetsPersistIntervalMs }} @@ -61,7 +54,6 @@ data: neo4j.bolt.server.disabled=true dns.name.prefix.frontend=FRONTEND - dns.name.prefix.ingestor=INGESTOR dns.name.prefix.coordinator=COORDINATOR dns.name.prefix.store=STORE @@ -118,7 +110,6 @@ data: -e "s/INDEX/${ordinal}/g" \ -e "s/KAFKA_SERVERS/${KAFKA_SERVERS}/g" \ -e "s/FRONTEND/${DNS_NAME_PREFIX_FRONTEND}/g" \ - -e "s/INGESTOR/${DNS_NAME_PREFIX_INGESTOR}/g" \ -e "s/COORDINATOR/${DNS_NAME_PREFIX_COORDINATOR}/g" \ -e "s/STORE/${DNS_NAME_PREFIX_STORE}/g" \ -e "s/PEGASUS_HOSTS/${pegasus_hosts}/g" \ diff --git a/charts/graphscope-store/templates/coordinator/statefulset.yaml b/charts/graphscope-store/templates/coordinator/statefulset.yaml index 3d16c5b343f1..466364ecdf96 100644 --- a/charts/graphscope-store/templates/coordinator/statefulset.yaml +++ b/charts/graphscope-store/templates/coordinator/statefulset.yaml @@ -1,5 +1,4 @@ {{- $frontendFullname := include "graphscope-store.frontend.fullname" . }} -{{- $ingestorFullname := include "graphscope-store.ingestor.fullname" . }} {{- $coordinatorFullname := include "graphscope-store.coordinator.fullname" . }} {{- $storeFullname := include "graphscope-store.store.fullname" . }} {{- $kafkaFullname := include "graphscope-store.kafka.fullname" . -}} @@ -110,16 +109,12 @@ spec: value: "coordinator" - name: FRONTEND_COUNT value: {{ .Values.frontend.replicaCount | quote }} - - name: INGESTOR_COUNT - value: {{ .Values.ingestor.replicaCount | quote }} - name: COORDINATOR_COUNT value: {{ .Values.coordinator.replicaCount | quote }} - name: STORE_COUNT value: {{ .Values.store.replicaCount | quote }} - name: DNS_NAME_PREFIX_FRONTEND value: {{ $frontendFullname }}-{}.{{ $frontendFullname }}-headless - - name: DNS_NAME_PREFIX_INGESTOR - value: {{ $ingestorFullname }}-{}.{{ $ingestorFullname }}-headless - name: DNS_NAME_PREFIX_COORDINATOR value: {{ $coordinatorFullname }}-{}.{{ $coordinatorFullname }}-headless - name: DNS_NAME_PREFIX_STORE diff --git a/charts/graphscope-store/templates/frontend/statefulset.yaml b/charts/graphscope-store/templates/frontend/statefulset.yaml index da00f410c2b6..c9919d197cfd 100644 --- a/charts/graphscope-store/templates/frontend/statefulset.yaml +++ b/charts/graphscope-store/templates/frontend/statefulset.yaml @@ -1,5 +1,4 @@ {{- $frontendFullname := include "graphscope-store.frontend.fullname" . }} -{{- $ingestorFullname := include "graphscope-store.ingestor.fullname" . }} {{- $coordinatorFullname := include "graphscope-store.coordinator.fullname" . }} {{- $storeFullname := include "graphscope-store.store.fullname" . }} {{- $kafkaFullname := include "graphscope-store.kafka.fullname" . -}} @@ -110,16 +109,12 @@ spec: value: "frontend" - name: FRONTEND_COUNT value: {{ .Values.frontend.replicaCount | quote }} - - name: INGESTOR_COUNT - value: {{ .Values.ingestor.replicaCount | quote }} - name: COORDINATOR_COUNT value: {{ .Values.coordinator.replicaCount | quote }} - name: STORE_COUNT value: {{ .Values.store.replicaCount | quote }} - name: DNS_NAME_PREFIX_FRONTEND value: {{ $frontendFullname }}-{}.{{ $frontendFullname }}-headless - - name: DNS_NAME_PREFIX_INGESTOR - value: {{ $ingestorFullname }}-{}.{{ $ingestorFullname }}-headless - name: DNS_NAME_PREFIX_COORDINATOR value: {{ $coordinatorFullname }}-{}.{{ $coordinatorFullname }}-headless - name: DNS_NAME_PREFIX_STORE diff --git a/charts/graphscope-store/templates/ingestor/statefulset.yaml b/charts/graphscope-store/templates/ingestor/statefulset.yaml deleted file mode 100644 index 0f32cf242470..000000000000 --- a/charts/graphscope-store/templates/ingestor/statefulset.yaml +++ /dev/null @@ -1,148 +0,0 @@ -{{- $frontendFullname := include "graphscope-store.frontend.fullname" . }} -{{- $ingestorFullname := include "graphscope-store.ingestor.fullname" . }} -{{- $coordinatorFullname := include "graphscope-store.coordinator.fullname" . }} -{{- $storeFullname := include "graphscope-store.store.fullname" . }} -{{- $kafkaFullname := include "graphscope-store.kafka.fullname" . -}} -{{- $releaseNamespace := .Release.Namespace }} -{{- $clusterDomain := .Values.clusterDomain }} - -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "graphscope-store.ingestor.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: ingestor - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} - {{- end }} -spec: - podManagementPolicy: {{ .Values.podManagementPolicy }} - replicas: {{ .Values.ingestor.replicaCount }} - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: ingestor - serviceName: {{ printf "%s-ingestor-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} - updateStrategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $ ) | nindent 4 }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: ingestor - {{- if .Values.ingestor.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.ingestor.podLabels "context" $) | nindent 8 }} - {{- end }} - annotations: - {{- if (include "graphscope-store.createConfigmap" .) }} - checksum/configuration: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - {{- end }} - {{- if .Values.ingestor.podAnnotations }} - {{- include "common.tplvalues.render" (dict "value" .Values.ingestor.podAnnotations "context" $) | nindent 8 }} - {{- end }} - spec: - {{- include "graphscope-store.imagePullSecrets" . | nindent 6 }} - {{- if .Values.ingestor.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.ingestor.hostAliases "context" $) | nindent 8 }} - {{- end }} - hostNetwork: {{ .Values.ingestor.hostNetwork }} - hostIPC: {{ .Values.ingestor.hostIPC }} - {{- if .Values.ingestor.schedulerName }} - schedulerName: {{ .Values.ingestor.schedulerName | quote }} - {{- end }} - {{- if .Values.affinity }} - affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "component" "ingestor" "context" $) | nindent 10 }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "component" "ingestor" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.dnsPolicy }} - dnsPolicy: {{ .Values.dnsPolicy | quote }} - {{- end }} - {{- if .Values.dnsConfig }} - dnsConfig: {{- include "common.tplvalues.render" (dict "value" .Values.dnsConfig "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.topologySpreadConstraints }} - topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.terminationGracePeriodSeconds }} - terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} - {{- end }} - {{- if .Values.priorityClassName }} - priorityClassName: {{ .Values.priorityClassName }} - {{- end }} - {{- if .Values.podSecurityContext.enabled }} - securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "graphscope-store.serviceAccountName" . }} - {{- if .Values.initContainers }} - initContainers: - {{- if .Values.initContainers }} - {{- include "common.tplvalues.render" ( dict "value" .Values.initContainers "context" $ ) | nindent 8 }} - {{- end }} - {{- end }} - containers: - - name: ingestor - image: {{ include "graphscope-store.image" . }} - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - {{- if .Values.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} - {{- if .Values.args }} - args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} - {{- end }} - env: - - name: GRAPH_NAME - value: {{ .Values.graphName | quote }} - - name: GROOT_JAVA_OPTS - value: {{ .Values.javaOpts | quote }} - - name: ROLE - value: "ingestor" - - name: FRONTEND_COUNT - value: {{ .Values.frontend.replicaCount | quote }} - - name: INGESTOR_COUNT - value: {{ .Values.ingestor.replicaCount | quote }} - - name: COORDINATOR_COUNT - value: {{ .Values.coordinator.replicaCount | quote }} - - name: STORE_COUNT - value: {{ .Values.store.replicaCount | quote }} - - name: DNS_NAME_PREFIX_FRONTEND - value: {{ $frontendFullname }}-{}.{{ $frontendFullname }}-headless - - name: DNS_NAME_PREFIX_INGESTOR - value: {{ $ingestorFullname }}-{}.{{ $ingestorFullname }}-headless - - name: DNS_NAME_PREFIX_COORDINATOR - value: {{ $coordinatorFullname }}-{}.{{ $coordinatorFullname }}-headless - - name: DNS_NAME_PREFIX_STORE - value: {{ $storeFullname }}-{}.{{ $storeFullname }}-headless - - name: DNS_NAME_SERVICE_KAFKA - value: {{ $kafkaFullname}}-headless.{{ $releaseNamespace }} - - name: KAFKA_SERVERS - value: {{ include "graphscope-store.kafka.brokerlist" . }} - ports: - - name: port - containerPort: 55555 - {{- if .Values.ingestor.resources }} - resources: {{- toYaml .Values.ingestor.resources | nindent 12 }} - {{- end }} - volumeMounts: - - name: config - mountPath: /etc/groot/groot.config.tpl - subPath: groot.config - - name: config - mountPath: /etc/groot/setup.sh - subPath: setup.sh - volumes: - - name: config - configMap: - name: {{ include "graphscope-store.configmapName" . }} - defaultMode: 0755 diff --git a/charts/graphscope-store/templates/ingestor/svc-headless.yaml b/charts/graphscope-store/templates/ingestor/svc-headless.yaml deleted file mode 100644 index 8d529fed39d0..000000000000 --- a/charts/graphscope-store/templates/ingestor/svc-headless.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ printf "%s-ingestor-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} - namespace: {{ .Release.Namespace }} - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: ingestor - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} - {{- end }} - annotations: - {{- if .Values.commonAnnotations }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - clusterIP: None - publishNotReadyAddresses: true - ports: - - name: port - port: {{ .Values.ingestor.service.port }} - targetPort: port - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: ingestor diff --git a/charts/graphscope-store/templates/store/statefulset.yaml b/charts/graphscope-store/templates/store/statefulset.yaml index 8748e69f8e1c..ba087dbfc3a8 100644 --- a/charts/graphscope-store/templates/store/statefulset.yaml +++ b/charts/graphscope-store/templates/store/statefulset.yaml @@ -1,5 +1,4 @@ {{- $frontendFullname := include "graphscope-store.frontend.fullname" . }} -{{- $ingestorFullname := include "graphscope-store.ingestor.fullname" . }} {{- $coordinatorFullname := include "graphscope-store.coordinator.fullname" . }} {{- $storeFullname := include "graphscope-store.store.fullname" . }} {{- $kafkaFullname := include "graphscope-store.kafka.fullname" . -}} @@ -110,16 +109,12 @@ spec: value: "store" - name: FRONTEND_COUNT value: {{ .Values.frontend.replicaCount | quote }} - - name: INGESTOR_COUNT - value: {{ .Values.ingestor.replicaCount | quote }} - name: COORDINATOR_COUNT value: {{ .Values.coordinator.replicaCount | quote }} - name: STORE_COUNT value: {{ .Values.store.replicaCount | quote }} - name: DNS_NAME_PREFIX_FRONTEND value: {{ $frontendFullname }}-{}.{{ $frontendFullname }}-headless - - name: DNS_NAME_PREFIX_INGESTOR - value: {{ $ingestorFullname }}-{}.{{ $ingestorFullname }}-headless - name: DNS_NAME_PREFIX_COORDINATOR value: {{ $coordinatorFullname }}-{}.{{ $coordinatorFullname }}-headless - name: DNS_NAME_PREFIX_STORE diff --git a/charts/graphscope-store/values.yaml b/charts/graphscope-store/values.yaml index 996a7673f045..122ebe409982 100644 --- a/charts/graphscope-store/values.yaml +++ b/charts/graphscope-store/values.yaml @@ -195,48 +195,6 @@ frontend: ## schedulerName: "" -## GraphScope Ingestor parameters -## -ingestor: - replicaCount: 2 - ## GraphScope store container's resource requests and limits - ## ref: http://kubernetes.io/docs/user-guide/compute-resources/ - ## - resources: {} - - ## GraphScope store Service parameters - ## - service: - type: ClusterIP - port: 55555 - annotations: {} - - ## @param hostAliases pods host aliases - ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ - ## - hostAliases: [] - ## @param hostNetwork Specify if host network should be enabled for pods - ## - hostNetwork: false - ## @param hostIPC Specify if host IPC should be enabled for pods - ## - hostIPC: false - ## @param podLabels Extra labels for pods - ## Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - ## - podLabels: {} - ## @param podAnnotations Extra annotations for pods - ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ - ## - podAnnotations: {} - ## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` - ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity - ## - - ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ - ## - schedulerName: "" - ## GraphScope Coordinator parameters ## coordinator: @@ -499,11 +457,6 @@ rpcMaxBytesMb: 20 discoveryMode: "file" -## Ingestor Config -ingestorQueueBufferMaxCount: 102400 -ingestorSenderBufferMaxCount: 102400 -ingestorSenderOperationMaxCount: 102400 - ## Coordinator Config snapshotIncreaseIntervalMs: 1000 offsetsPersistIntervalMs: 3000 diff --git a/docs/storage_engine/groot.md b/docs/storage_engine/groot.md index 960c1b575c4e..c21d882c0a5f 100644 --- a/docs/storage_engine/groot.md +++ b/docs/storage_engine/groot.md @@ -71,14 +71,13 @@ helm status demo | auth.username | Username. If empty, then there's no authentication | "" | | auth.password | Password | "" | | store.replicaCount | Number of Store Pod | 2 | -| ingestor.replicaCount | Number of Ingestor Pod | 2 | | dataset.modern | Load [modern graph](https://tinkerpop.apache.org/docs/current/tutorials/getting-started/) dataset at the start | false | | frontend.replicaCount | Number of Frontend | 1 | | frontend.service.type | Kubernetes Service type of frontend | NodePort | | frontend.query.per.second.limit | the maximum qps can be handled by frontend service | 2147483647 (without limitation) | -If Groot is launched with the default configuration, then two Store Pods, one Frontend Pod, one Ingestor Pod, and one Coordinator Pod will be started. The number of Coordinator nodes is fixed to 1. +If Groot is launched with the default configuration, then two Store Pods, one Frontend Pod, and one Coordinator Pod will be started. The number of Coordinator nodes is fixed to 1. Use the `--set key=value[,key=value]` command to set the parameters for `helm install`, for example: @@ -662,7 +661,7 @@ Groot stores the graph data in `/var/lib/graphscope-store` directory in the Stor You can view the logs of each Pod using the command `kubectl logs ${POD_NAME}`. - It is common to check the logs of Frontend and Store roles. When debugging, it is often necessary to check the logs of Coordinator and Ingestor as well. The logs of Frontend include the logs of the Compiler that generates the logical query plan, while the logs of Store include the logs of the query engine execution. For example, + It is common to check the logs of Frontend and Store roles. When debugging, it is often necessary to check the logs of Coordinator as well. The logs of Frontend include the logs of the Compiler that generates the logical query plan, while the logs of Store include the logs of the query engine execution. For example, ```bash kubectl logs demo-graphscope-store-frontend-0 diff --git a/docs/utilities/how_to_find_logs.md b/docs/utilities/how_to_find_logs.md index cf02c7a4e5c1..c2fc474afdc9 100644 --- a/docs/utilities/how_to_find_logs.md +++ b/docs/utilities/how_to_find_logs.md @@ -95,15 +95,13 @@ $ cat /home/graphscope/graphlearn.INFO ## Find logs for Groot -It is common to find the logs of Frontend and Store roles. When debugging, it is often necessary to find the logs of Coordinator and Ingestor as well. The logs of Frontend include the logs of the Compiler that generates the logical query plan, while the logs of Store include the logs of the query engine execution. You can find the logs of each Pod using the [kubectl command](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands) `kubectl logs ${POD_NAME}`. For example, +It is common to find the logs of Frontend and Store roles. When debugging, it is often necessary to find the logs of Coordinator as well. The logs of Frontend include the logs of the Compiler that generates the logical query plan, while the logs of Store include the logs of the query engine execution. You can find the logs of each Pod using the [kubectl command](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands) `kubectl logs ${POD_NAME}`. For example, ```bash $ kubectl get pod NAME READY STATUS RESTARTS AGE demo-graphscope-store-coordinator-0 1/1 Running 0 33d demo-graphscope-store-frontend-0 1/1 Running 0 33d -demo-graphscope-store-ingestor-0 1/1 Running 0 33d -demo-graphscope-store-ingestor-1 1/1 Running 0 33d demo-graphscope-store-store-0 1/1 Running 0 33d demo-graphscope-store-store-1 1/1 Running 0 33d diff --git a/interactive_engine/assembly/src/conf/groot/config.template b/interactive_engine/assembly/src/conf/groot/config.template index 8a3f055be2b4..84a1a4cd3f8f 100644 --- a/interactive_engine/assembly/src/conf/groot/config.template +++ b/interactive_engine/assembly/src/conf/groot/config.template @@ -4,9 +4,7 @@ node.idx= rpc.port=0 store.node.count=1 frontend.node.count=1 -ingestor.node.count=2 coordinator.node.count=1 -ingestor.queue.count=2 partition.count=4 discovery.mode=zookeeper diff --git a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/RoleType.java b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/RoleType.java index 402b2930355e..b7bef6e6a6a4 100644 --- a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/RoleType.java +++ b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/RoleType.java @@ -19,7 +19,6 @@ public enum RoleType { UNKNOWN("unknown"), FRONTEND("frontend"), - INGESTOR("ingestor"), STORE("store"), COORDINATOR("coordinator"), FRONTEND_SERVICE("frontend_service"), diff --git a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/CommonConfig.java b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/CommonConfig.java index b71032800092..002f9398fba0 100644 --- a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/CommonConfig.java +++ b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/CommonConfig.java @@ -33,8 +33,6 @@ public class CommonConfig { Config.stringConfig("frontend.rpc.port", ""); public static final Config COORDINATOR_RPC_PORT = Config.stringConfig("coordinator.rpc.port", ""); - public static final Config INGESTOR_RPC_PORT = - Config.stringConfig("ingestor.rpc.port", ""); public static final Config STORE_RPC_PORT = Config.stringConfig("store.rpc.port", ""); public static final Config RPC_THREAD_COUNT = @@ -55,15 +53,9 @@ public class CommonConfig { public static final Config FRONTEND_NODE_COUNT = Config.intConfig(String.format(NODE_COUNT_FORMAT, RoleType.FRONTEND.getName()), 1); - public static final Config INGESTOR_NODE_COUNT = - Config.intConfig(String.format(NODE_COUNT_FORMAT, RoleType.INGESTOR.getName()), 2); - public static final Config COORDINATOR_NODE_COUNT = Config.intConfig(String.format(NODE_COUNT_FORMAT, RoleType.COORDINATOR.getName()), 1); - public static final Config INGESTOR_QUEUE_COUNT = - Config.intConfig("ingestor.queue.count", 2); - public static final Config PARTITION_COUNT = Config.intConfig("partition.count", 1); public static final Config METRIC_UPDATE_INTERVAL_MS = diff --git a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/DiscoveryConfig.java b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/DiscoveryConfig.java index 24d6be49f2a5..484a5c305595 100644 --- a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/DiscoveryConfig.java +++ b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/DiscoveryConfig.java @@ -24,10 +24,6 @@ public class DiscoveryConfig { Config.stringConfig( String.format(DNS_NAME_PREFIX_FORMAT, RoleType.FRONTEND.getName()), ""); - public static final Config DNS_NAME_PREFIX_INGESTOR = - Config.stringConfig( - String.format(DNS_NAME_PREFIX_FORMAT, RoleType.INGESTOR.getName()), ""); - public static final Config DNS_NAME_PREFIX_COORDINATOR = Config.stringConfig( String.format(DNS_NAME_PREFIX_FORMAT, RoleType.COORDINATOR.getName()), ""); diff --git a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/FrontendConfig.java b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/FrontendConfig.java index 5df7d5d47421..ed2fb1e211c5 100644 --- a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/FrontendConfig.java +++ b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/FrontendConfig.java @@ -31,4 +31,7 @@ public class FrontendConfig { public static final Config ENABLE_HASH_GENERATE_EID = Config.boolConfig("enable.hash.generate.eid", false); + + public static final Config WRITE_QUEUE_BUFFER_MAX_COUNT = + Config.intConfig("write.queue.buffer.max.count", 1024000); } diff --git a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/IngestorConfig.java b/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/IngestorConfig.java deleted file mode 100644 index 4c70d347ad14..000000000000 --- a/interactive_engine/common/src/main/java/com/alibaba/graphscope/groot/common/config/IngestorConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.common.config; - -public class IngestorConfig { - public static final Config INGESTOR_QUEUE_BUFFER_MAX_COUNT = - Config.intConfig("ingestor.queue.buffer.max.count", 102400); - - public static final Config INGESTOR_SENDER_BUFFER_MAX_COUNT = - Config.intConfig("ingestor.sender.buffer.max.count", 102400); - - public static final Config INGESTOR_SENDER_OPERATION_MAX_COUNT = - Config.intConfig("ingestor.sender.operation.max.count", 102400); - - public static final Config INGESTOR_CHECK_PROCESSOR_INTERVAL_MS = - Config.longConfig("ingestor.check.processor.interval.ms", 2000L); -} diff --git a/interactive_engine/executor/engine/pegasus/network/src/manager.rs b/interactive_engine/executor/engine/pegasus/network/src/manager.rs index 31315b9c1d18..a4a272610577 100644 --- a/interactive_engine/executor/engine/pegasus/network/src/manager.rs +++ b/interactive_engine/executor/engine/pegasus/network/src/manager.rs @@ -108,8 +108,16 @@ impl SimpleServerDetector { pub fn update_peer_view>(&self, peer_view: Iter) { let new_peers = peer_view .map(|(id, server_addr)| { - let addr = server_addr.to_socket_addr().unwrap(); - Server { id, addr } + loop { + let addr = server_addr.to_socket_addr(); + if addr.is_ok() { + let addr = addr.unwrap(); + return Server { id, addr } + } else { + error!("Cannot resolve address {:?}, retrying...", server_addr); + sleep(Duration::from_secs(3)); + } + } }) .collect::>(); let mut peers = self diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/Utils.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/Utils.java index f77705d6d235..0cd6daed8265 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/Utils.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/Utils.java @@ -17,15 +17,22 @@ import com.alibaba.graphscope.groot.common.config.CommonConfig; import com.alibaba.graphscope.groot.common.config.Configs; import com.alibaba.graphscope.groot.common.config.DiscoveryConfig; +import com.alibaba.graphscope.groot.operation.OperationBatch; +import com.alibaba.graphscope.groot.operation.OperationBlob; +import com.alibaba.graphscope.groot.operation.OperationType; + +import java.util.List; public class Utils { + public static final OperationBatch MARKER_BATCH = + OperationBatch.newBuilder() + .addOperationBlob(OperationBlob.MARKER_OPERATION_BLOB) + .build(); public static String getHostTemplate(Configs configs, RoleType role) { switch (role) { case FRONTEND: return DiscoveryConfig.DNS_NAME_PREFIX_FRONTEND.get(configs); - case INGESTOR: - return DiscoveryConfig.DNS_NAME_PREFIX_INGESTOR.get(configs); case COORDINATOR: return DiscoveryConfig.DNS_NAME_PREFIX_COORDINATOR.get(configs); case STORE: @@ -54,9 +61,6 @@ public static int getPort(Configs configs, RoleType role, int idx) { case FRONTEND: s = CommonConfig.FRONTEND_RPC_PORT.get(configs); break; - case INGESTOR: - s = CommonConfig.INGESTOR_RPC_PORT.get(configs); - break; case COORDINATOR: s = CommonConfig.COORDINATOR_RPC_PORT.get(configs); break; @@ -86,4 +90,30 @@ public static int getPort(Configs configs, RoleType role, int idx) { return Integer.parseInt(array[idx]); } } + + public static OperationBatch extractOperations( + OperationBatch input, List types) { + boolean hasOtherType = false; + for (int i = 0; i < input.getOperationCount(); ++i) { + OperationBlob blob = input.getOperationBlob(i); + OperationType opType = blob.getOperationType(); + if (!types.contains(opType)) { + hasOtherType = true; + break; + } + } + if (!hasOtherType) { + return input; + } + OperationBatch.Builder batchBuilder = OperationBatch.newBuilder(); + batchBuilder.setLatestSnapshotId(input.getLatestSnapshotId()); + for (int i = 0; i < input.getOperationCount(); ++i) { + OperationBlob blob = input.getOperationBlob(i); + OperationType opType = blob.getOperationType(); + if (types.contains(opType)) { + batchBuilder.addOperationBlob(blob); + } + } + return batchBuilder.build(); + } } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/BackupManager.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/BackupManager.java index 17ba491db35b..571c1d9380bd 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/BackupManager.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/BackupManager.java @@ -23,6 +23,7 @@ import com.alibaba.graphscope.groot.common.exception.GrootException; import com.alibaba.graphscope.groot.common.util.BackupInfo; import com.alibaba.graphscope.groot.common.util.ThreadFactoryUtils; +import com.alibaba.graphscope.groot.meta.FileMetaStore; import com.alibaba.graphscope.groot.meta.MetaService; import com.alibaba.graphscope.groot.meta.MetaStore; import com.alibaba.graphscope.groot.store.StoreBackupId; @@ -449,9 +450,7 @@ public void onError(Throwable t) { private void restoreGraphMeta(int globalBackupId, String metaRestorePath) throws IOException { BackupInfo restoredBackupInfo = this.globalBackupIdToInfo.get(globalBackupId); - Configs.Builder builder = Configs.newBuilder(); - builder.put("file.meta.store.path", metaRestorePath); - MetaStore restoredMetaStore = new FileMetaStore(builder.build()); + MetaStore restoredMetaStore = new FileMetaStore(metaRestorePath); long restoredSnapshotId = restoredBackupInfo.getSnapshotId(); restoredMetaStore.write( diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/DdlWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/DdlWriter.java index a1cc89bd03e4..599e7c702fc7 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/DdlWriter.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/DdlWriter.java @@ -13,7 +13,6 @@ */ package com.alibaba.graphscope.groot.coordinator; -import com.alibaba.graphscope.groot.frontend.IngestorWriteClient; import com.alibaba.graphscope.groot.operation.BatchId; import com.alibaba.graphscope.groot.operation.OperationBatch; import com.alibaba.graphscope.groot.rpc.RoleClients; diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/GraphInitializer.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/GraphInitializer.java index eabf94c3b1fb..5a42ed0e2245 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/GraphInitializer.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/GraphInitializer.java @@ -82,7 +82,7 @@ private void initializeMetaIfNeeded() throws IOException { this.metaStore.write(SnapshotManager.WRITE_SNAPSHOT_ID_PATH, b); } if (!this.metaStore.exists(SnapshotManager.QUEUE_OFFSETS_PATH)) { - int queueCount = CommonConfig.INGESTOR_QUEUE_COUNT.get(this.configs); + int queueCount = CommonConfig.STORE_NODE_COUNT.get(this.configs); List offsets = new ArrayList<>(queueCount); for (int i = 0; i < queueCount; i++) { offsets.add(-1L); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestProgressService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestProgressService.java deleted file mode 100644 index c554d0d5282f..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestProgressService.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.coordinator; - -import com.alibaba.graphscope.proto.groot.GetTailOffsetsRequest; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsResponse; -import com.alibaba.graphscope.proto.groot.IngestProgressGrpc; - -import io.grpc.stub.StreamObserver; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -public class IngestProgressService extends IngestProgressGrpc.IngestProgressImplBase { - private static final Logger logger = LoggerFactory.getLogger(IngestProgressService.class); - - private final SnapshotManager snapshotManager; - - public IngestProgressService(SnapshotManager snapshotManager) { - this.snapshotManager = snapshotManager; - } - - @Override - public void getTailOffsets( - GetTailOffsetsRequest request, - StreamObserver responseObserver) { - logger.info("Get offset of {}", request.getQueueIdList()); - List queueIdList = request.getQueueIdList(); - List tailOffsets = this.snapshotManager.getTailOffsets(queueIdList); - GetTailOffsetsResponse response = - GetTailOffsetsResponse.newBuilder().addAllOffsets(tailOffsets).build(); - responseObserver.onNext(response); - responseObserver.onCompleted(); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteClient.java new file mode 100644 index 000000000000..c02a60125314 --- /dev/null +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteClient.java @@ -0,0 +1,42 @@ +/** + * Copyright 2020 Alibaba Group Holding Limited. + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + *

http://www.apache.org/licenses/LICENSE-2.0 + * + *

Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.graphscope.groot.coordinator; + +import com.alibaba.graphscope.groot.operation.BatchId; +import com.alibaba.graphscope.groot.operation.OperationBatch; +import com.alibaba.graphscope.groot.rpc.RpcClient; +import com.alibaba.graphscope.proto.groot.*; + +import io.grpc.ManagedChannel; + +public class IngestorWriteClient extends RpcClient { + + private final IngestorWriteGrpc.IngestorWriteBlockingStub stub; + + public IngestorWriteClient(ManagedChannel channel) { + super(channel); + this.stub = IngestorWriteGrpc.newBlockingStub(channel); + } + + public BatchId writeIngestor(String requestId, int queueId, OperationBatch operationBatch) { + WriteIngestorRequest request = + WriteIngestorRequest.newBuilder() + .setRequestId(requestId) + .setQueueId(queueId) + .setOperationBatch(operationBatch.toProto()) + .build(); + WriteIngestorResponse response = this.stub.writeIngestor(request); + return new BatchId(response.getSnapshotId()); + } +} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteSnapshotIdNotifier.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteSnapshotIdNotifier.java index b8080ced89d6..1992da2eddea 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteSnapshotIdNotifier.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/IngestorWriteSnapshotIdNotifier.java @@ -26,12 +26,12 @@ public class IngestorWriteSnapshotIdNotifier implements WriteSnapshotIdNotifier LoggerFactory.getLogger(IngestorWriteSnapshotIdNotifier.class); private final RoleClients ingestorSnapshotClients; - private final int ingestorCount; + private final int frontendCount; public IngestorWriteSnapshotIdNotifier( Configs configs, RoleClients ingestorSnapshotClients) { this.ingestorSnapshotClients = ingestorSnapshotClients; - this.ingestorCount = CommonConfig.INGESTOR_NODE_COUNT.get(configs); + this.frontendCount = CommonConfig.FRONTEND_NODE_COUNT.get(configs); } @Override @@ -51,7 +51,9 @@ public void onError(Throwable t) { logger.error("error in advanceIngestSnapshotId {}: {}", si, t.toString()); } }; - for (int i = 0; i < this.ingestorCount; i++) { + // TODO(siyuan): Send to frontend service + // for (int i = 0; i < this.frontendCount; i++) { + for (int i = 0; i < 1; i++) { try { IngestorSnapshotClient client = ingestorSnapshotClients.getClient(i); client.advanceIngestSnapshotId(si, callback); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/NotifyFrontendListener.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/NotifyFrontendListener.java index 6b9ce0a5baa5..4e7f842e9456 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/NotifyFrontendListener.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/NotifyFrontendListener.java @@ -14,6 +14,7 @@ package com.alibaba.graphscope.groot.coordinator; import com.alibaba.graphscope.groot.CompletionCallback; +import com.alibaba.graphscope.groot.common.exception.ServiceNotReadyException; import com.alibaba.graphscope.groot.common.schema.wrapper.GraphDef; import org.slf4j.Logger; @@ -43,7 +44,13 @@ public NotifyFrontendListener( @Override public void snapshotAdvanced(long snapshotId, long ddlSnapshotId) { - GraphDef graphDef = this.schemaManager.getGraphDef(); + GraphDef graphDef; + try { + graphDef = this.schemaManager.getGraphDef(); + } catch (ServiceNotReadyException ex) { + logger.warn("Schema manager is not ready: {}", ex.getMessage()); + return; + } logger.debug("snapshot advanced to {}-{}, will notify frontend", snapshotId, ddlSnapshotId); this.frontendSnapshotClient.advanceQuerySnapshot( snapshotId, diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/SnapshotManager.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/SnapshotManager.java index 777e2280a52c..528a082b0e29 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/SnapshotManager.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/SnapshotManager.java @@ -115,7 +115,6 @@ public class SnapshotManager { private final WriteSnapshotIdNotifier writeSnapshotIdNotifier; private final int storeCount; - private final int queueCount; private final long snapshotIncreaseIntervalMs; private final long offsetsPersistIntervalMs; @@ -123,7 +122,7 @@ public class SnapshotManager { private volatile long writeSnapshotId; private final Map storeToSnapshotInfo; - private final Map> storeToOffsets; + private final Map storeToOffsets; private AtomicReference> queueOffsetsRef; private ScheduledExecutorService increaseWriteSnapshotIdScheduler; @@ -137,7 +136,7 @@ public class SnapshotManager { private final ObjectMapper objectMapper; - private boolean isSecondary; + private final boolean isSecondary; public SnapshotManager( Configs configs, @@ -149,7 +148,6 @@ public SnapshotManager( this.writeSnapshotIdNotifier = writeSnapshotIdNotifier; this.objectMapper = new ObjectMapper(); - this.queueCount = CommonConfig.INGESTOR_QUEUE_COUNT.get(configs); this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); this.snapshotIncreaseIntervalMs = @@ -253,19 +251,16 @@ private void recover() throws IOException { byte[] offsetBytes = this.metaStore.read(QUEUE_OFFSETS_PATH); List offsets = objectMapper.readValue(offsetBytes, new TypeReference<>() {}); logger.info("recovered queue offsets {}", offsets); - if (isSecondary) { - offsets = offsets.subList(0, 1); - } - if (offsets.size() != this.queueCount) { + if (offsets.size() != this.storeCount) { throw new IllegalStateException( "recovered queueCount [" + offsets.size() + "], but expect queueCount [" - + this.queueCount + + this.storeCount + "]"); } - for (int i = 0; i < this.queueCount; i++) { + for (int i = 0; i < this.storeCount; i++) { long recoveredOffset = offsets.get(i); try (LogReader reader = logService.createReader(i, recoveredOffset + 1)) { } catch (Exception e) { @@ -304,21 +299,15 @@ public synchronized void commitSnapshotId( storeId, (k, v) -> { if (v != null) { - if (v.size() != queueOffsets.size()) { + if (1 != queueOffsets.size()) { throw new IllegalArgumentException( - "current offset size [" - + v.size() - + "], commit offset size [" - + queueOffsets.size() - + "]"); + "committed offset is [" + queueOffsets + "]"); } - for (int i = 0; i < v.size(); i++) { - if (v.get(i) > queueOffsets.get(i)) { - return v; - } + if (v > queueOffsets.get(0)) { + return v; } } - return queueOffsets; + return queueOffsets.get(0); }); maybeUpdateQuerySnapshotId(); } @@ -367,7 +356,7 @@ private void maybeUpdateQuerySnapshotId() { if (snapshotId > currentSnapshotId) { try { if (ddlSnapshotId < currentDdlSnapshotId) { - // During failover, store might send smaller ddlSnapshotId + // During fail over, store might send smaller ddlSnapshotId minSnapshotInfo = new SnapshotInfo(snapshotId, currentDdlSnapshotId); // throw new // IllegalStateException("minSnapshotInfo [" + minSnapshotInfo + @@ -448,8 +437,8 @@ private void updateQueueOffsets() throws IOException { boolean changed = false; for (int qId = 0; qId < queueOffsets.size(); qId++) { long minOffset = Long.MAX_VALUE; - for (List storeOffsets : this.storeToOffsets.values()) { - minOffset = Math.min(storeOffsets.get(qId), minOffset); + for (Long storeOffsets : this.storeToOffsets.values()) { + minOffset = Math.min(storeOffsets, minOffset); } if (minOffset != Long.MAX_VALUE && minOffset > newQueueOffsets.get(qId)) { newQueueOffsets.set(qId, minOffset); @@ -470,22 +459,6 @@ private void persistObject(Object value, String path) throws IOException { metaStore.write(path, b); } - /** - * Get offset list according to the input queueId list. This is for IngestNode to get the - * correct start offset for replay. - * - * @param queueIdList - * @return - */ - public List getTailOffsets(List queueIdList) { - List tailOffsets = new ArrayList<>(queueIdList.size()); - List queueOffsets = this.queueOffsetsRef.get(); - for (int queueId : queueIdList) { - tailOffsets.add(queueOffsets.get(queueId)); - } - return tailOffsets; - } - public List getQueueOffsets() { return this.queueOffsetsRef.get(); } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/discovery/FileDiscovery.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/discovery/FileDiscovery.java index 54ca52f0c951..c9b01dd3dcbd 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/discovery/FileDiscovery.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/discovery/FileDiscovery.java @@ -38,7 +38,6 @@ public FileDiscovery(Configs configs) { // Store related nodes String storePrefix = DiscoveryConfig.DNS_NAME_PREFIX_STORE.get(configs); String frontendPrefix = DiscoveryConfig.DNS_NAME_PREFIX_FRONTEND.get(configs); - String ingestorPrefix = DiscoveryConfig.DNS_NAME_PREFIX_INGESTOR.get(configs); String coordinatorPrefix = DiscoveryConfig.DNS_NAME_PREFIX_COORDINATOR.get(configs); // Frontend nodes @@ -47,12 +46,6 @@ public FileDiscovery(Configs configs) { makeRoleNodes(frontendCount, frontendPrefix, FRONTEND); this.allNodes.put(FRONTEND, frontendNodes); - // Ingestor nodes - int ingestorCount = CommonConfig.INGESTOR_NODE_COUNT.get(configs); - Map ingestorNodes = - makeRoleNodes(ingestorCount, ingestorPrefix, INGESTOR); - this.allNodes.put(INGESTOR, ingestorNodes); - // Coordinator nodes int coordinatorCount = CommonConfig.COORDINATOR_NODE_COUNT.get(configs); Map coordinatorNodes = diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientService.java index 2dc00fdc4534..4627ab85afc3 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientService.java @@ -46,19 +46,19 @@ public class ClientService extends ClientGrpc.ClientImplBase { private final SnapshotCache snapshotCache; private final MetricsAggregator metricsAggregator; - private final StoreIngestor storeIngestor; + private final StoreIngestClients storeIngestor; private final MetaService metaService; private final BatchDdlClient batchDdlClient; - private final StoreStateFetcher storeStateFetcher; + private final StoreStateClients storeStateFetcher; public ClientService( SnapshotCache snapshotCache, MetricsAggregator metricsAggregator, - StoreIngestor storeIngestor, + StoreIngestClients storeIngestor, MetaService metaService, BatchDdlClient batchDdlClient, - StoreStateFetcher storeStateFetcher) { + StoreStateClients storeStateFetcher) { this.snapshotCache = snapshotCache; this.metricsAggregator = metricsAggregator; this.storeIngestor = storeIngestor; diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientWriteService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientWriteService.java index eb7a1ff0f6b3..ed31ab3ec775 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientWriteService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/ClientWriteService.java @@ -12,6 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -116,8 +117,14 @@ public void replayRecords( long offset = request.getOffset(); long timestamp = request.getTimestamp(); logger.info("replay records from offset {}, timestamp {}", offset, timestamp); - List ids = graphWriter.replayWALFrom(offset, timestamp); - responseObserver.onNext(ReplayRecordsResponse.newBuilder().addAllSnapshotId(ids).build()); - responseObserver.onCompleted(); + try { + List ids = graphWriter.replayWALFrom(offset, timestamp); + responseObserver.onNext( + ReplayRecordsResponse.newBuilder().addAllSnapshotId(ids).build()); + responseObserver.onCompleted(); + } catch (IOException e) { + logger.error("replayRecords failed", e); + responseObserver.onError(e); + } } } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorSnapshotService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorSnapshotService.java similarity index 62% rename from interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorSnapshotService.java rename to interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorSnapshotService.java index 1e7b00270135..9f8e6ba999a4 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorSnapshotService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorSnapshotService.java @@ -1,31 +1,23 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; +package com.alibaba.graphscope.groot.frontend; import com.alibaba.graphscope.groot.CompletionCallback; +import com.alibaba.graphscope.groot.frontend.write.KafkaAppender; import com.alibaba.graphscope.proto.groot.AdvanceIngestSnapshotIdRequest; import com.alibaba.graphscope.proto.groot.AdvanceIngestSnapshotIdResponse; import com.alibaba.graphscope.proto.groot.IngestorSnapshotGrpc; import io.grpc.stub.StreamObserver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class IngestorSnapshotService extends IngestorSnapshotGrpc.IngestorSnapshotImplBase { + private static final Logger logger = LoggerFactory.getLogger(IngestorSnapshotService.class); - private final IngestService ingestService; + private final KafkaAppender kafkaAppender; - public IngestorSnapshotService(IngestService ingestService) { - this.ingestService = ingestService; + public IngestorSnapshotService(KafkaAppender kafkaAppender) { + this.kafkaAppender = kafkaAppender; } @Override @@ -33,7 +25,7 @@ public void advanceIngestSnapshotId( AdvanceIngestSnapshotIdRequest request, StreamObserver responseObserver) { long snapshotId = request.getSnapshotId(); - this.ingestService.advanceIngestSnapshotId( + this.kafkaAppender.advanceIngestSnapshotId( snapshotId, new CompletionCallback() { @Override diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteClient.java deleted file mode 100644 index 2c18e1998fa6..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteClient.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.frontend; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.operation.BatchId; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.rpc.RpcClient; -import com.alibaba.graphscope.proto.groot.*; - -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; - -import java.util.List; - -public class IngestorWriteClient extends RpcClient { - - private final IngestorWriteGrpc.IngestorWriteBlockingStub stub; - private IngestorWriteGrpc.IngestorWriteStub asyncStub; - - public IngestorWriteClient(ManagedChannel channel) { - super(channel); - this.stub = IngestorWriteGrpc.newBlockingStub(channel); - this.asyncStub = IngestorWriteGrpc.newStub(channel); - } - - public IngestorWriteClient(IngestorWriteGrpc.IngestorWriteBlockingStub stub) { - super((ManagedChannel) stub.getChannel()); - this.stub = stub; - } - - public BatchId writeIngestor(String requestId, int queueId, OperationBatch operationBatch) { - WriteIngestorRequest request = - WriteIngestorRequest.newBuilder() - .setRequestId(requestId) - .setQueueId(queueId) - .setOperationBatch(operationBatch.toProto()) - .build(); - WriteIngestorResponse response = this.stub.writeIngestor(request); - return new BatchId(response.getSnapshotId()); - } - - public List replayWALFrom(long offset, long timestamp) { - ReplayWALRequest request = - ReplayWALRequest.newBuilder().setOffset(offset).setTimestamp(timestamp).build(); - ReplayWALResponse response = stub.replayWAL(request); - return response.getSnapshotIdList(); - } - - public void writeIngestorAsync( - String requestId, - int queueId, - OperationBatch operationBatch, - CompletionCallback callback) { - WriteIngestorRequest request = - WriteIngestorRequest.newBuilder() - .setRequestId(requestId) - .setQueueId(queueId) - .setOperationBatch(operationBatch.toProto()) - .build(); - this.asyncStub.writeIngestor( - request, - new StreamObserver() { - @Override - public void onNext(WriteIngestorResponse response) { - callback.onCompleted(response.getSnapshotId()); - } - - @Override - public void onError(Throwable t) { - callback.onError(t); - } - - @Override - public void onCompleted() {} - }); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorWriteService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteService.java similarity index 68% rename from interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorWriteService.java rename to interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteService.java index 4b0aa67d1f96..2c3b623056e7 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestorWriteService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/IngestorWriteService.java @@ -11,34 +11,31 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.graphscope.groot.ingestor; +package com.alibaba.graphscope.groot.frontend; +import com.alibaba.graphscope.groot.frontend.write.KafkaAppender; +import com.alibaba.graphscope.groot.ingestor.IngestCallback; import com.alibaba.graphscope.groot.operation.OperationBatch; import com.alibaba.graphscope.proto.groot.*; -import io.grpc.Status; import io.grpc.stub.StreamObserver; -import java.util.List; - public class IngestorWriteService extends IngestorWriteGrpc.IngestorWriteImplBase { - private final IngestService ingestService; + private final KafkaAppender kafkaAppender; - public IngestorWriteService(IngestService ingestService) { - this.ingestService = ingestService; + public IngestorWriteService(KafkaAppender kafkaAppender) { + this.kafkaAppender = kafkaAppender; } @Override public void writeIngestor( WriteIngestorRequest request, StreamObserver responseObserver) { try { - int queueId = request.getQueueId(); String requestId = request.getRequestId(); OperationBatch operationBatch = OperationBatch.parseProto(request.getOperationBatch()); - this.ingestService.ingestBatch( + this.kafkaAppender.ingestBatch( requestId, - queueId, operationBatch, new IngestCallback() { @Override @@ -60,18 +57,4 @@ public void onFailure(Exception e) { responseObserver.onError(e); } } - - @Override - public void replayWAL( - ReplayWALRequest request, StreamObserver responseObserver) { - try { - List ids = - ingestService.replayDMLRecordsFrom(request.getOffset(), request.getTimestamp()); - responseObserver.onNext(ReplayWALResponse.newBuilder().addAllSnapshotId(ids).build()); - } catch (Exception e) { - responseObserver.onError( - Status.INVALID_ARGUMENT.withDescription(e.getMessage()).asRuntimeException()); - } - responseObserver.onCompleted(); - } } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/SnapshotUpdateClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/SnapshotUpdateClient.java index 920afcf9c18b..4db297d19ccc 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/SnapshotUpdateClient.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/SnapshotUpdateClient.java @@ -37,12 +37,6 @@ public SnapshotUpdateClient(ManagedChannel channel) { this.stub = CoordinatorSnapshotServiceGrpc.newBlockingStub(channel); } - public SnapshotUpdateClient( - CoordinatorSnapshotServiceGrpc.CoordinatorSnapshotServiceBlockingStub stub) { - super((ManagedChannel) stub.getChannel()); - this.stub = stub; - } - public void updateSnapshot(int frontendId, long snapshotId) throws RuntimeException { UpdateMinQuerySnapshotIdRequest req = UpdateMinQuerySnapshotIdRequest.newBuilder() diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClient.java index ebaddb795f9d..7cdbfac4e045 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClient.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClient.java @@ -42,7 +42,7 @@ public void storeIngest( builder.putAllConfig(config); this.stub.storeIngest( builder.build(), - new StreamObserver() { + new StreamObserver<>() { @Override public void onNext(StoreIngestResponse value) { callback.onCompleted(null); @@ -61,7 +61,7 @@ public void onCompleted() {} public void storeClearIngest(String path, CompletionCallback callback) { this.stub.storeClearIngest( StoreClearIngestRequest.newBuilder().setDataPath(path).build(), - new StreamObserver() { + new StreamObserver<>() { @Override public void onNext(StoreClearIngestResponse storeClearIngestResponse) { callback.onCompleted(null); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClients.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClients.java index ea2d2008b291..b9af665f3321 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClients.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreIngestClients.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.function.Function; -public class StoreIngestClients extends RoleClients implements StoreIngestor { +public class StoreIngestClients extends RoleClients { public StoreIngestClients( ChannelManager channelManager, @@ -33,12 +33,10 @@ public StoreIngestClients( super(channelManager, targetRole, clientBuilder); } - @Override public void ingest(int storeId, String path, CompletionCallback callback) { this.ingest(storeId, path, new HashMap(), callback); } - @Override public void ingest( int storeId, String path, @@ -47,7 +45,6 @@ public void ingest( this.getClient(storeId).storeIngest(path, config, callback); } - @Override public void clearIngest(int storeId, String path, CompletionCallback callback) { this.getClient(storeId).storeClearIngest(path, callback); } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateClients.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateClients.java index 5a3a721f11d5..b9ed4a6847b6 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateClients.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateClients.java @@ -22,7 +22,7 @@ import java.util.function.Function; -public class StoreStateClients extends RoleClients implements StoreStateFetcher { +public class StoreStateClients extends RoleClients { public StoreStateClients( ChannelManager channelManager, diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateFetcher.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateFetcher.java deleted file mode 100644 index c34effad4c4d..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/StoreStateFetcher.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.frontend; - -import com.alibaba.graphscope.proto.groot.GetStoreStateResponse; - -public interface StoreStateFetcher { - GetStoreStateResponse getDiskState(int storeId); -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/GraphWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/GraphWriter.java index 3bb8abacfdd5..267c6e3e49fd 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/GraphWriter.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/GraphWriter.java @@ -13,11 +13,8 @@ import com.alibaba.graphscope.groot.common.schema.wrapper.EdgeKind; import com.alibaba.graphscope.groot.common.schema.wrapper.LabelId; import com.alibaba.graphscope.groot.common.schema.wrapper.PropertyValue; -import com.alibaba.graphscope.groot.common.util.EdgeRecordKey; -import com.alibaba.graphscope.groot.common.util.PkHashUtils; -import com.alibaba.graphscope.groot.common.util.VertexRecordKey; -import com.alibaba.graphscope.groot.common.util.WriteSessionUtil; -import com.alibaba.graphscope.groot.frontend.IngestorWriteClient; +import com.alibaba.graphscope.groot.common.util.*; +import com.alibaba.graphscope.groot.ingestor.IngestCallback; import com.alibaba.graphscope.groot.meta.MetaService; import com.alibaba.graphscope.groot.metrics.MetricsAgent; import com.alibaba.graphscope.groot.metrics.MetricsCollector; @@ -26,20 +23,18 @@ import com.alibaba.graphscope.groot.operation.OperationType; import com.alibaba.graphscope.groot.operation.VertexId; import com.alibaba.graphscope.groot.operation.dml.*; -import com.alibaba.graphscope.groot.rpc.RoleClients; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; public class GraphWriter implements MetricsAgent { + private static final Logger logger = LoggerFactory.getLogger(GraphWriter.class); public static final String WRITE_REQUESTS_TOTAL = "write.requests.total"; public static final String WRITE_REQUESTS_PER_SECOND = "write.requests.per.second"; @@ -63,26 +58,56 @@ public class GraphWriter implements MetricsAgent { private SnapshotCache snapshotCache; private EdgeIdGenerator edgeIdGenerator; private MetaService metaService; - private RoleClients ingestWriteClients; private AtomicLong lastWrittenSnapshotId = new AtomicLong(0L); - private static final Logger logger = LoggerFactory.getLogger(GraphWriter.class); + private final KafkaAppender kafkaAppender; + private ScheduledExecutorService scheduler; public GraphWriter( SnapshotCache snapshotCache, EdgeIdGenerator edgeIdGenerator, MetaService metaService, - RoleClients ingestWriteClients, MetricsCollector metricsCollector, + KafkaAppender appender, Configs configs) { this.snapshotCache = snapshotCache; this.edgeIdGenerator = edgeIdGenerator; this.metaService = metaService; - this.ingestWriteClients = ingestWriteClients; initMetrics(); metricsCollector.register(this, this::updateMetrics); // default for increment eid generate this.enableHashEid = FrontendConfig.ENABLE_HASH_GENERATE_EID.get(configs); + + this.kafkaAppender = appender; + } + + public void start() { + this.scheduler = + Executors.newSingleThreadScheduledExecutor( + ThreadFactoryUtils.daemonThreadFactoryWithLogExceptionHandler( + "kafka-appender-try-start", logger)); + + this.scheduler.scheduleWithFixedDelay( + this::tryStartProcessors, 0, 2000, TimeUnit.MILLISECONDS); + } + + public void stop() { + if (this.scheduler != null) { + this.scheduler.shutdown(); + try { + this.scheduler.awaitTermination(3000L, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Ignore + } + this.scheduler = null; + } + kafkaAppender.stop(); + } + + private void tryStartProcessors() { + if (!kafkaAppender.isStarted()) { + kafkaAppender.start(); + } } public long writeBatch( @@ -152,49 +177,27 @@ public void writeBatch( } } OperationBatch operationBatch = batchBuilder.build(); - int writeQueueId = getWriteQueueId(writeSession); - int ingestorId = this.metaService.getIngestorIdForQueue(writeQueueId); - long startTimeNano = System.nanoTime(); - this.ingestWriteClients - .getClient(ingestorId) - .writeIngestorAsync( - requestId, - writeQueueId, - operationBatch, - new CompletionCallback() { - @Override - public void onCompleted(Long res) { - long writeSnapshotId = res; - lastWrittenSnapshotId.updateAndGet( - x -> Math.max(x, writeSnapshotId)); - writeRequestsTotal.addAndGet(writeRequests.size()); - finish(); - callback.onCompleted(res); - } - - @Override - public void onError(Throwable t) { - finish(); - callback.onError(t); - } - - void finish() { - long ingestorCompleteTimeNano = System.nanoTime(); - ingestorBlockTimeNano.addAndGet( - ingestorCompleteTimeNano - startTimeNano); - pendingWriteCount.decrementAndGet(); - } - }); + this.kafkaAppender.ingestBatch( + requestId, + operationBatch, + new IngestCallback() { + @Override + public void onSuccess(long snapshotId) { + lastWrittenSnapshotId.updateAndGet(x -> Math.max(x, snapshotId)); + writeRequestsTotal.addAndGet(writeRequests.size()); + callback.onCompleted(snapshotId); + } + + @Override + public void onFailure(Exception e) { + callback.onError(e); + } + }); } - public List replayWALFrom(long offset, long timestamp) { + public List replayWALFrom(long offset, long timestamp) throws IOException { List allIds = new ArrayList<>(); - for (int queue = 0; queue < metaService.getQueueCount(); ++queue) { - int id = metaService.getIngestorIdForQueue(queue); - List ids = ingestWriteClients.getClient(id).replayWALFrom(offset, timestamp); - allIds.addAll(ids); - } - return allIds; + return kafkaAppender.replayDMLRecordsFrom(offset, timestamp); } public boolean flushSnapshot(long snapshotId, long waitTimeMs) throws InterruptedException { @@ -208,15 +211,6 @@ public boolean flushLastSnapshot(long waitTimeMs) throws InterruptedException { return this.flushSnapshot(snapshotId, waitTimeMs); } - private int getWriteQueueId(String session) { - int queueCount = this.metaService.getQueueCount(); - if (queueCount <= 1) { - throw new IllegalStateException("expect queueCount > 1, but was [" + queueCount + "]"); - } - long clientIdx = WriteSessionUtil.getClientIdx(session); - return (int) (clientIdx % (queueCount - 1)) + 1; - } - private void addDeleteEdgeOperation( OperationBatch.Builder batchBuilder, GraphSchema schema, DataRecord dataRecord) { EdgeId edgeId = getEdgeId(schema, dataRecord, false); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/KafkaAppender.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/KafkaAppender.java new file mode 100644 index 000000000000..517383eee306 --- /dev/null +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/frontend/write/KafkaAppender.java @@ -0,0 +1,309 @@ +package com.alibaba.graphscope.groot.frontend.write; + +import static com.alibaba.graphscope.groot.Utils.MARKER_BATCH; + +import com.alibaba.graphscope.groot.CompletionCallback; +import com.alibaba.graphscope.groot.Utils; +import com.alibaba.graphscope.groot.common.config.CommonConfig; +import com.alibaba.graphscope.groot.common.config.Configs; +import com.alibaba.graphscope.groot.common.config.FrontendConfig; +import com.alibaba.graphscope.groot.common.exception.IngestRejectException; +import com.alibaba.graphscope.groot.common.util.PartitionUtils; +import com.alibaba.graphscope.groot.ingestor.IngestCallback; +import com.alibaba.graphscope.groot.meta.MetaService; +import com.alibaba.graphscope.groot.operation.OperationBatch; +import com.alibaba.graphscope.groot.operation.OperationBlob; +import com.alibaba.graphscope.groot.operation.OperationType; +import com.alibaba.graphscope.groot.wal.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; + +public class KafkaAppender { + private static final Logger logger = LoggerFactory.getLogger(KafkaAppender.class); + + private final MetaService metaService; + private final LogService logService; + + private final int queue; + + private final int storeCount; + private final int partitionCount; + private final int bufferSize; + private BlockingQueue ingestBuffer; + private Thread ingestThread; + + private boolean shouldStop = false; + private boolean started = false; + + private final AtomicLong ingestSnapshotId; + + public KafkaAppender(Configs configs, MetaService metaService, LogService logService) { + this.metaService = metaService; + this.logService = logService; + this.queue = CommonConfig.NODE_IDX.get(configs); + this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); + this.partitionCount = metaService.getPartitionCount(); + this.bufferSize = FrontendConfig.WRITE_QUEUE_BUFFER_MAX_COUNT.get(configs); + this.ingestSnapshotId = new AtomicLong(-1); + } + + public void start() { + logger.info("staring KafkaAppender queue#[{}]", queue); + this.ingestBuffer = new ArrayBlockingQueue<>(this.bufferSize); + + this.shouldStop = false; + this.ingestThread = + new Thread( + () -> { + LogWriter logWriter = this.logService.createWriter(); + while (!shouldStop) { + try { + process(logWriter); + } catch (Exception e) { + logger.warn("error occurred in ingest process", e); + } + } + try { + logWriter.close(); + } catch (IOException e) { + logger.warn("close logWriter failed", e); + } + }); + this.ingestThread.setDaemon(true); + this.ingestThread.start(); + this.started = true; + } + + public boolean isStarted() { + return this.started; + } + + public void stop() { + logger.info("stopping KafkaAppender queue#[{}]", queue); + this.shouldStop = true; + this.started = false; + if (this.ingestThread != null && this.ingestThread.isAlive()) { + try { + this.ingestThread.interrupt(); + this.ingestThread.join(); + } catch (InterruptedException e) { + logger.warn("stop KafkaAppender queue#[] interrupted"); + } + this.ingestThread = null; + } + } + + public void ingestBatch( + String requestId, OperationBatch operationBatch, IngestCallback callback) { + checkStarted(); + // logger.info("ingestBatch requestId [{}]", requestId); + if (this.ingestSnapshotId.get() == -1L) { + throw new IllegalStateException("ingestor has no valid ingestSnapshotId"); + } + boolean suc = this.ingestBuffer.offer(new IngestTask(requestId, operationBatch, callback)); + if (!suc) { + logger.warn("ingest buffer is full"); + throw new IngestRejectException("add ingestTask to buffer failed"); + } + } + + private void process(LogWriter logWriter) { + IngestTask task; + try { + if ((task = this.ingestBuffer.poll(1000L, TimeUnit.MILLISECONDS)) == null) { + return; + } + } catch (InterruptedException e) { + logger.warn("polling ingestBuffer interrupted"); + return; + } + try { + long batchSnapshotId = processTask(logWriter, task); + task.callback.onSuccess(batchSnapshotId); + } catch (Exception e) { + task.callback.onFailure(e); + } + logger.debug("batch ingested. requestId [" + task.requestId + "]"); + } + + private long processTask(LogWriter logWriter, IngestTask task) throws IOException { + long batchSnapshotId = this.ingestSnapshotId.get(); + if (batchSnapshotId == -1L) { + throw new IllegalStateException("invalid ingestSnapshotId [" + batchSnapshotId + "]"); + } + logger.debug( + "append batch to WAL. requestId [{}], snapshotId [{}]", + task.requestId, + batchSnapshotId); + long latestSnapshotId = task.operationBatch.getLatestSnapshotId(); + if (latestSnapshotId > 0 && latestSnapshotId < batchSnapshotId) { + throw new IllegalStateException( + "latestSnapshotId [" + + latestSnapshotId + + "] must >= batchSnapshotId [" + + batchSnapshotId + + "]"); + } + if (!shouldStop) { + try { + Map builderMap = splitBatch(task.operationBatch); + for (Map.Entry entry : builderMap.entrySet()) { + int storeId = entry.getKey(); + OperationBatch batch = entry.getValue().build(); + // logger.info("Log writer append partitionId [{}]", storeId); + logWriter.append(storeId, new LogEntry(batchSnapshotId, batch)); + } + } catch (Exception e) { + // write failed, just throw out to fail this task + logger.error("write WAL failed. requestId [" + task.requestId + "]", e); + throw e; + } + } + if (shouldStop) { + throw new IllegalStateException("ingestProcessor queue stopped"); + } + return batchSnapshotId; + } + + private void checkStarted() { + if (!started) { + throw new IllegalStateException("IngestProcessor queue not started"); + } + } + + class IngestTask { + String requestId; + OperationBatch operationBatch; + IngestCallback callback; + + public IngestTask( + String requestId, OperationBatch operationBatch, IngestCallback callback) { + this.requestId = requestId; + this.operationBatch = operationBatch; + this.callback = callback; + } + } + + public Map splitBatch(OperationBatch operationBatch) { + Map storeToBatchBuilder = new HashMap<>(); + Function storeDataBatchBuilderFunc = + k -> OperationBatch.newBuilder(); + for (OperationBlob operationBlob : operationBatch) { + long partitionKey = operationBlob.getPartitionKey(); + if (partitionKey == -1L) { + // replicate to all store node + for (int i = 0; i < this.storeCount; i++) { + OperationBatch.Builder batchBuilder = + storeToBatchBuilder.computeIfAbsent(i, storeDataBatchBuilderFunc); + batchBuilder.addOperationBlob(operationBlob); + } + } else { + int partitionId = + PartitionUtils.getPartitionIdFromKey(partitionKey, partitionCount); + int storeId = metaService.getStoreIdByPartition(partitionId); + OperationBatch.Builder batchBuilder = + storeToBatchBuilder.computeIfAbsent(storeId, storeDataBatchBuilderFunc); + batchBuilder.addOperationBlob(operationBlob); + } + } + return storeToBatchBuilder; + } + + public List replayDMLRecordsFrom(long offset, long timestamp) throws IOException { + List types = new ArrayList<>(); + types.add(OperationType.OVERWRITE_VERTEX); + types.add(OperationType.UPDATE_VERTEX); + types.add(OperationType.DELETE_VERTEX); + types.add(OperationType.OVERWRITE_EDGE); + types.add(OperationType.UPDATE_EDGE); + types.add(OperationType.DELETE_EDGE); + types.add(OperationType.CLEAR_VERTEX_PROPERTIES); + types.add(OperationType.CLEAR_EDGE_PROPERTIES); + + logger.info("replay DML records of from offset [{}], ts [{}]", offset, timestamp); + + long batchSnapshotId = this.ingestSnapshotId.get(); + int replayCount = 0; + + try (LogWriter logWriter = this.logService.createWriter()) { + for (int storeId = 0; storeId < storeCount; ++storeId) { + try (LogReader logReader = + this.logService.createReader(storeId, offset, timestamp)) { + ReadLogEntry readLogEntry; + while (!shouldStop && (readLogEntry = logReader.readNext()) != null) { + LogEntry logEntry = readLogEntry.getLogEntry(); + OperationBatch batch = + Utils.extractOperations(logEntry.getOperationBatch(), types); + if (batch.getOperationCount() == 0) { + continue; + } + logWriter.append(storeId, new LogEntry(batchSnapshotId, batch)); + replayCount++; + } + } + } + } + + logger.info("replay DML records finished. total replayed [{}] records", replayCount); + return List.of(batchSnapshotId); + } + + /** + * This method will update writeSnapshotId and returns the previous value. + * + *

SnapshotManager periodically increase the writeSnapshotId and call this method to update + * the writeSnapshotId for each Ingestor. + * + * @param snapshotId + * @return + */ + public synchronized void advanceIngestSnapshotId( + long snapshotId, CompletionCallback callback) { + checkStarted(); + logger.debug("ingestor advance snapshot id: {}", snapshotId); + long previousSnapshotId = this.ingestSnapshotId.getAndUpdate(x -> Math.max(x, snapshotId)); + if (previousSnapshotId >= snapshotId) { + throw new IllegalStateException( + "current ingestSnapshotId [" + + previousSnapshotId + + "], cannot update to [" + + snapshotId + + "]"); + } + try { + ingestBatch( + "marker", + MARKER_BATCH, + new IngestCallback() { + @Override + public void onSuccess(long snapshotId) { + callback.onCompleted(previousSnapshotId); + } + + @Override + public void onFailure(Exception e) { + logger.warn("ingest marker failed. snapshotId {}", snapshotId, e); + callback.onError(e); + } + }); + } catch (IllegalStateException e) { + logger.warn("ingest marker failed, snapshotId {}, {}", snapshotId, e.getMessage()); + callback.onError(e); + } catch (Exception e) { + logger.warn("ingest marker failed. snapshotId {}", snapshotId, e); + callback.onError(e); + } + } +} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/BatchSender.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/BatchSender.java deleted file mode 100644 index bc5c06573ba4..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/BatchSender.java +++ /dev/null @@ -1,340 +0,0 @@ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.IngestorConfig; -import com.alibaba.graphscope.groot.common.config.StoreConfig; -import com.alibaba.graphscope.groot.common.util.PartitionUtils; -import com.alibaba.graphscope.groot.meta.MetaService; -import com.alibaba.graphscope.groot.metrics.AvgMetric; -import com.alibaba.graphscope.groot.metrics.MetricsAgent; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.operation.OperationBlob; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; -import com.alibaba.graphscope.groot.operation.StoreDataBatch.Builder; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class BatchSender implements MetricsAgent { - private static final Logger logger = LoggerFactory.getLogger(BatchSender.class); - - public static final String SEND_BYTES_PER_SECOND = "send.bytes.per.second"; - public static final String SEND_BYTES_TOTAL = "send.bytes.total"; - public static final String SEND_RECORDS_PER_SECOND = "send.records.per.second"; - public static final String SEND_RECORDS_TOTAL = "send.records.total"; - public static final String SEND_BUFFER_BATCH_COUNT = "send.buffer.batch.count"; - public static final String SEND_CALLBACK_LATENCY = "send.callback.latency.per.second.ms"; - - private final MetaService metaService; - private final StoreWriter storeWriter; - - private final int bufferSize; - private final int storeCount; - private final int sendOperationLimit; - - private List> storeSendBuffer; - private BlockingQueue sendTasks; - - private Thread sendThread; - private volatile boolean shouldStop = true; - - private volatile long lastUpdateTime; - private AvgMetric sendBytesMetric; - private AvgMetric sendRecordsMetric; - private List callbackLatencyMetrics; - private final int receiverQueueSize; - - public BatchSender( - Configs configs, - MetaService metaService, - StoreWriter storeWriter, - MetricsCollector metricsCollector) { - this.metaService = metaService; - this.storeWriter = storeWriter; - - this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); - this.bufferSize = IngestorConfig.INGESTOR_SENDER_BUFFER_MAX_COUNT.get(configs); - this.sendOperationLimit = IngestorConfig.INGESTOR_SENDER_OPERATION_MAX_COUNT.get(configs); - this.receiverQueueSize = StoreConfig.STORE_QUEUE_BUFFER_SIZE.get(configs); - initMetrics(); - metricsCollector.register(this, this::updateMetrics); - } - - public void start() { - this.storeSendBuffer = new ArrayList<>(this.storeCount); - this.sendTasks = new ArrayBlockingQueue<>(this.storeCount); - for (int i = 0; i < this.storeCount; i++) { - this.storeSendBuffer.add(new ArrayBlockingQueue<>(this.bufferSize)); - this.sendTasks.add(new SendTask(i, null)); - } - - this.shouldStop = false; - this.sendThread = - new Thread( - () -> { - while (!shouldStop) { - try { - sendBatch(); - } catch (Exception e) { - logger.warn("error occurred in send process", e); - } - } - }); - this.sendThread.setDaemon(true); - this.sendThread.start(); - } - - public void stop() { - this.shouldStop = true; - if (this.sendThread != null && this.sendThread.isAlive()) { - try { - this.sendThread.interrupt(); - this.sendThread.join(); - } catch (InterruptedException e) { - logger.warn("stop batchSender failed", e); - } - this.sendThread = null; - } - } - - public void asyncSendWithRetry( - String requestId, - int queueId, - long snapshotId, - long offset, - OperationBatch operationBatch) { - int partitionCount = metaService.getPartitionCount(); - Map storeToBatchBuilder = new HashMap<>(); - Function storeDataBatchBuilderFunc = - k -> - StoreDataBatch.newBuilder() - .requestId(requestId) - .queueId(queueId) - .snapshotId(snapshotId) - .offset(offset); - for (OperationBlob operationBlob : operationBatch) { - long partitionKey = operationBlob.getPartitionKey(); - if (partitionKey == -1L) { - // replicate to all store node - for (int i = 0; i < this.storeCount; i++) { - StoreDataBatch.Builder batchBuilder = - storeToBatchBuilder.computeIfAbsent(i, storeDataBatchBuilderFunc); - batchBuilder.addOperation(-1, operationBlob); - } - } else { - int partitionId = - PartitionUtils.getPartitionIdFromKey(partitionKey, partitionCount); - int storeId = metaService.getStoreIdByPartition(partitionId); - StoreDataBatch.Builder batchBuilder = - storeToBatchBuilder.computeIfAbsent(storeId, storeDataBatchBuilderFunc); - batchBuilder.addOperation(partitionId, operationBlob); - } - } - storeToBatchBuilder.forEach( - (storeId, batchBuilder) -> { - while (!shouldStop) { - try { - BlockingQueue curBuffer = storeSendBuffer.get(storeId); - if (curBuffer.remainingCapacity() == 0) { - logger.warn("Buffer of store [{}] is full", storeId); - } - curBuffer.put(batchBuilder.build()); - break; - } catch (InterruptedException e) { - logger.warn("send buffer interrupted"); - } - } - }); - } - - class SendTask { - int storeId; - int retryCount = 0; - List dataToRetry; - - public SendTask(int storeId, List dataToRetry) { - this(storeId, 0, dataToRetry); - } - - public SendTask(int storeId, int retryCount, List dataToRetry) { - this.storeId = storeId; - this.retryCount = retryCount; - this.dataToRetry = dataToRetry; - } - - public void retry() { - retryCount += 1; - } - } - - private void sendBatch() { - SendTask sendTask; - try { - sendTask = this.sendTasks.poll(1000L, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.warn("polling send task interrupted"); - return; - } - if (sendTask == null) { - return; - } - - int storeId = sendTask.storeId; - int retryCount = sendTask.retryCount; - List dataToSend = sendTask.dataToRetry; - - if (retryCount > 0) { - try { - Thread.sleep(100); - } catch (InterruptedException ignored) { - - } - } - - if (retryCount > 1000) { - logger.error("Failed to send batch of {}", dataToSend); - return; - } - - if (dataToSend == null) { - dataToSend = new ArrayList<>(); - BlockingQueue buffer = this.storeSendBuffer.get(storeId); - StoreDataBatch dataBatch; - int operationCount = 0; - int batchCount = 0; - while (operationCount < this.sendOperationLimit - && batchCount < this.receiverQueueSize) { - try { - dataBatch = buffer.poll(100L, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - dataBatch = null; - logger.warn("polling send buffer interrupted, {}", e.getMessage()); - } - if (dataBatch == null) { - break; - } - dataToSend.add(dataBatch); - operationCount += dataBatch.getSize(); - batchCount++; - } - } - - if (dataToSend.size() > 0) { - List finalDataToSend = dataToSend; - long beforeWriteTime = System.nanoTime(); - this.storeWriter.write( - storeId, - dataToSend, - new CompletionCallback() { - @Override - public void onCompleted(Integer res) { - sendBytesMetric.add(res); - sendRecordsMetric.add( - finalDataToSend.stream() - .collect( - Collectors.summingInt( - batch -> batch.getSize()))); - finish(true); - } - - @Override - public void onError(Throwable t) { - logger.warn( - "send to store [" + storeId + "] failed. will retry later", t); - finish(false); - } - - private void finish(boolean suc) { - long finishTime = System.nanoTime(); - callbackLatencyMetrics.get(storeId).add(finishTime - beforeWriteTime); - if (suc) { - addTask(storeId, 0, null); - } else { - addTask(storeId, retryCount + 1, finalDataToSend); - } - } - }); - } else { - addTask(storeId, 0, null); - } - } - - private void addTask(int storeId, int retryCount, List dataToRetry) { - if (!sendTasks.offer(new SendTask(storeId, retryCount, dataToRetry))) { - logger.error("failed to add task. storeId [{}]", storeId); - } - } - - @Override - public void initMetrics() { - this.lastUpdateTime = System.nanoTime(); - this.sendBytesMetric = new AvgMetric(); - this.sendRecordsMetric = new AvgMetric(); - this.callbackLatencyMetrics = new ArrayList<>(this.storeCount); - for (int i = 0; i < this.storeCount; i++) { - this.callbackLatencyMetrics.add(new AvgMetric()); - } - } - - private void updateMetrics() { - long currentTime = System.nanoTime(); - long interval = currentTime - this.lastUpdateTime; - this.sendBytesMetric.update(interval); - this.sendRecordsMetric.update(interval); - this.callbackLatencyMetrics.forEach(m -> m.update(interval)); - this.lastUpdateTime = currentTime; - } - - @Override - public Map getMetrics() { - return new HashMap() { - { - put( - SEND_BYTES_PER_SECOND, - String.valueOf((int) (1000000000 * sendBytesMetric.getAvg()))); - put(SEND_BYTES_TOTAL, String.valueOf(sendBytesMetric.getLastUpdateTotal())); - put( - SEND_RECORDS_PER_SECOND, - String.valueOf((int) (1000000000 * sendRecordsMetric.getAvg()))); - put(SEND_RECORDS_TOTAL, String.valueOf(sendRecordsMetric.getLastUpdateTotal())); - put( - SEND_BUFFER_BATCH_COUNT, - String.valueOf( - storeSendBuffer.stream() - .map(q -> q.size()) - .collect(Collectors.toList()))); - put( - SEND_CALLBACK_LATENCY, - String.valueOf( - callbackLatencyMetrics.stream() - .map(m -> (int) (1000 * m.getAvg())) - .collect(Collectors.toList()))); - } - }; - } - - @Override - public String[] getMetricKeys() { - return new String[] { - SEND_BYTES_PER_SECOND, - SEND_BYTES_TOTAL, - SEND_RECORDS_PER_SECOND, - SEND_RECORDS_TOTAL, - SEND_BUFFER_BATCH_COUNT, - SEND_CALLBACK_LATENCY - }; - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProcessor.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProcessor.java deleted file mode 100644 index 6714547958d1..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProcessor.java +++ /dev/null @@ -1,470 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.IngestorConfig; -import com.alibaba.graphscope.groot.common.exception.IngestRejectException; -import com.alibaba.graphscope.groot.metrics.MetricsAgent; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.operation.OperationBlob; -import com.alibaba.graphscope.groot.operation.OperationType; -import com.alibaba.graphscope.groot.wal.LogEntry; -import com.alibaba.graphscope.groot.wal.LogReader; -import com.alibaba.graphscope.groot.wal.LogService; -import com.alibaba.graphscope.groot.wal.LogWriter; -import com.alibaba.graphscope.groot.wal.ReadLogEntry; -import com.alibaba.graphscope.groot.wal.readonly.ReadOnlyLogReader; - -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -/** A IngestProcessor handles one ingest queue */ -public class IngestProcessor implements MetricsAgent { - private static final Logger logger = LoggerFactory.getLogger(IngestProcessor.class); - - public static final String WRITE_RECORDS_PER_SECOND = "write.records.per.second"; - public static final String WRITE_RECORDS_TOTAL = "write.records.total"; - public static final String WAL_BLOCK_PER_SECOND_MS = "wal.block.per.second.ms"; - public static final String STORE_BLOCK_PER_SECOND_MS = "store.block.per.second.ms"; - public static final String INGESTOR_REJECT_COUNT = "ingestor.reject.count"; - public static final String INGEST_BUFFER_TASKS_COUNT = "ingest.buffer.tasks.count"; - - private volatile boolean shouldStop = true; - private volatile long tailOffset; - - private final int queueId; - private final int bufferSize; - private BlockingQueue ingestBuffer; - private Thread ingestThread; - private Thread tailWALThread; - private final AtomicLong ingestSnapshotId; - - private final LogService logService; - private final BatchSender batchSender; - private volatile boolean started; - - // For metrics - private volatile long totalProcessed; - private volatile long lastUpdateTime; - private volatile long lastUpdateProcessed; - private volatile long writeRecordsPerSecond; - private volatile long walBlockTimeNano; - private volatile long storeBlockTimeNano; - private AtomicLong ingestorRejectCount; - private volatile long lastUpdateWalBlockTimeNano; - private volatile long walBlockPerSecondMs; - private volatile long lastUpdateStoreBlockTimeNano; - private volatile long storeBlockPerSecondMs; - private boolean isSecondary; - - public IngestProcessor( - Configs configs, - LogService logService, - BatchSender batchSender, - int queueId, - AtomicLong ingestSnapshotId, - MetricsCollector metricsCollector) { - this.logService = logService; - this.batchSender = batchSender; - this.queueId = queueId; - this.ingestSnapshotId = ingestSnapshotId; - - this.bufferSize = IngestorConfig.INGESTOR_QUEUE_BUFFER_MAX_COUNT.get(configs); - this.isSecondary = CommonConfig.SECONDARY_INSTANCE_ENABLED.get(configs); - - initMetrics(); - metricsCollector.register(this, this::updateMetrics); - } - - public void start() { - logger.info("staring ingestProcessor queue#[" + queueId + "]"); - this.ingestBuffer = new ArrayBlockingQueue<>(this.bufferSize); - - this.shouldStop = false; - this.batchSender.start(); - this.ingestThread = - new Thread( - () -> { - while (!shouldStop) { - try { - replayWAL(this.tailOffset); - break; - } catch (Exception e) { - logger.error("error occurred before ingest, retrying", e); - try { - Thread.sleep(1000L); - } catch (InterruptedException ie) { - // Ignore - } - } - } - LogWriter logWriter = this.logService.createWriter(this.queueId); - while (!shouldStop) { - try { - process(logWriter); - } catch (Exception e) { - logger.warn("error occurred in ingest process", e); - } - } - try { - logWriter.close(); - } catch (IOException e) { - logger.warn("close logWriter failed", e); - } - }); - this.ingestThread.setDaemon(true); - this.ingestThread.start(); - if (isSecondary) { - this.tailWALThread = - new Thread( - () -> { - try { - tailWAL(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - this.tailWALThread.setDaemon(true); - this.tailWALThread.start(); - } - - started = true; - logger.info("ingestProcessor queue#[" + queueId + "] started"); - } - - public void stop() { - logger.info("stopping ingestProcessor queue#[" + queueId + "]"); - this.shouldStop = true; - this.started = false; - if (this.ingestThread != null && this.ingestThread.isAlive()) { - try { - this.ingestThread.interrupt(); - this.ingestThread.join(); - } catch (InterruptedException e) { - logger.warn("stop ingestProcessor queue#[" + queueId + "] interrupted"); - } - this.ingestThread = null; - } - if (tailWALThread != null && tailWALThread.isAlive()) { - try { - this.tailWALThread.interrupt(); - this.tailWALThread.join(); - } catch (InterruptedException e) { - logger.warn("stop ingestProcessor queue#[" + queueId + "] interrupted"); - } - this.tailWALThread = null; - } - this.batchSender.stop(); - logger.debug("ingestProcessor queue#[" + queueId + "] stopped"); - } - - private void checkStarted() { - if (!started) { - throw new IllegalStateException("IngestProcessor queue#[" + queueId + "] not started"); - } - } - - public boolean isStarted() { - return started; - } - - public void ingestBatch( - String requestId, OperationBatch operationBatch, IngestCallback callback) { - checkStarted(); - logger.debug("ingestBatch requestId [{}], queueId [{}]", requestId, queueId); - if (this.ingestSnapshotId.get() == -1L) { - throw new IllegalStateException("ingestor has no valid ingestSnapshotId"); - } - - boolean suc = this.ingestBuffer.offer(new IngestTask(requestId, operationBatch, callback)); - if (!suc) { - logger.warn("ingest buffer is full"); - this.ingestorRejectCount.incrementAndGet(); - throw new IngestRejectException("add ingestTask to buffer failed"); - } - } - - private void process(LogWriter logWriter) { - IngestTask task; - try { - task = this.ingestBuffer.poll(1000L, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - logger.warn("polling ingestBuffer interrupted"); - return; - } - if (task == null) { - return; - } - try { - long batchSnapshotId = processTask(logWriter, task); - task.callback.onSuccess(batchSnapshotId); - } catch (Exception e) { - task.callback.onFailure(e); - } - logger.debug("batch ingested. requestId [" + task.requestId + "]"); - } - - private long processTask(LogWriter logWriter, IngestTask task) throws IOException { - long batchSnapshotId = this.ingestSnapshotId.get(); - if (batchSnapshotId == -1L) { - throw new IllegalStateException("invalid ingestSnapshotId [" + batchSnapshotId + "]"); - } - logger.debug( - "append batch to WAL. requestId [{}], snapshotId [{}]", - task.requestId, - batchSnapshotId); - long latestSnapshotId = task.operationBatch.getLatestSnapshotId(); - if (latestSnapshotId > 0 && latestSnapshotId < batchSnapshotId) { - throw new IllegalStateException( - "latestSnapshotId [" - + latestSnapshotId - + "] must >= batchSnapshotId [" - + batchSnapshotId - + "]"); - } - long startTimeNano = System.nanoTime(); - long walOffset = -1L; - if (!shouldStop) { - try { - walOffset = logWriter.append(new LogEntry(batchSnapshotId, task.operationBatch)); - } catch (Exception e) { - // write failed, just throw out to fail this task - logger.error("write WAL failed. requestId [" + task.requestId + "]", e); - throw e; - } - } - long walCompleteTimeNano = System.nanoTime(); - if (shouldStop) { - throw new IllegalStateException("ingestProcessor queue#[" + this.queueId + "] stopped"); - } - this.batchSender.asyncSendWithRetry( - task.requestId, this.queueId, batchSnapshotId, walOffset, task.operationBatch); - long storeCompleteTimeNano = System.nanoTime(); - if (!task.operationBatch.equals(IngestService.MARKER_BATCH)) { - this.walBlockTimeNano += (walCompleteTimeNano - startTimeNano); - this.storeBlockTimeNano += (storeCompleteTimeNano - walCompleteTimeNano); - this.totalProcessed += task.operationBatch.getOperationCount(); - } - return batchSnapshotId; - } - - class IngestTask { - String requestId; - OperationBatch operationBatch; - IngestCallback callback; - - public IngestTask( - String requestId, OperationBatch operationBatch, IngestCallback callback) { - this.requestId = requestId; - this.operationBatch = operationBatch; - this.callback = callback; - } - } - - public void setTailOffset(long offset) { - logger.info("IngestProcessor of queue #[{}] set tail offset to [{}]", queueId, offset); - this.tailOffset = offset; - } - - public void tailWAL() throws IOException { - List types = new ArrayList<>(); - types.add(OperationType.CREATE_VERTEX_TYPE); - types.add(OperationType.CREATE_EDGE_TYPE); - types.add(OperationType.ADD_EDGE_KIND); - types.add(OperationType.DROP_VERTEX_TYPE); - types.add(OperationType.DROP_EDGE_TYPE); - types.add(OperationType.REMOVE_EDGE_KIND); - types.add(OperationType.PREPARE_DATA_LOAD); - types.add(OperationType.COMMIT_DATA_LOAD); - try (ReadOnlyLogReader reader = (ReadOnlyLogReader) logService.createReader(queueId, 0)) { - while (!shouldStop) { - ConsumerRecords records = reader.getLatestUpdates(); - for (ConsumerRecord record : records) { - long offset = record.offset(); - LogEntry logEntry = record.value(); - OperationBatch batch = extractOperations(logEntry.getOperationBatch(), types); - long snapshotId = logEntry.getSnapshotId(); - if (batch.getOperationCount() > 0) { - long batchSnapshotId = this.ingestSnapshotId.get(); - this.batchSender.asyncSendWithRetry( - "", queueId, batchSnapshotId, offset, batch); - logger.info( - "Sent logEntry snapshot Id {}, SnapshotId {}, batch {}", - snapshotId, - batchSnapshotId, - batch.toProto()); - } - } - } - } - } - - public void replayWAL(long tailOffset) throws IOException { - long replayFrom = tailOffset + 1; - logger.info("replay WAL of queue#[{}] from offset [{}]", queueId, replayFrom); - int replayCount = 0; - try (LogReader logReader = this.logService.createReader(queueId, replayFrom)) { - ReadLogEntry readLogEntry; - while (!shouldStop && (readLogEntry = logReader.readNext()) != null) { - long offset = readLogEntry.getOffset(); - LogEntry logEntry = readLogEntry.getLogEntry(); - long snapshotId = logEntry.getSnapshotId(); - OperationBatch batch = logEntry.getOperationBatch(); - this.batchSender.asyncSendWithRetry("", queueId, snapshotId, offset, batch); - if (!batch.equals(IngestService.MARKER_BATCH)) { - replayCount++; - } - } - } - logger.info("replayWAL finished. total replayed [{}] records", replayCount); - } - - public long replayDMLRecordsFrom(long offset, long timestamp) throws IOException { - List types = new ArrayList<>(); - types.add(OperationType.OVERWRITE_VERTEX); - types.add(OperationType.UPDATE_VERTEX); - types.add(OperationType.DELETE_VERTEX); - types.add(OperationType.OVERWRITE_EDGE); - types.add(OperationType.UPDATE_EDGE); - types.add(OperationType.DELETE_EDGE); - types.add(OperationType.CLEAR_VERTEX_PROPERTIES); - types.add(OperationType.CLEAR_EDGE_PROPERTIES); - - long batchSnapshotId = this.ingestSnapshotId.get(); - logger.info( - "replay DML records of queue#[{}] from offset [{}], ts [{}]", - queueId, - offset, - timestamp); - int replayCount = 0; - try (LogReader logReader = this.logService.createReader(queueId, offset, timestamp)) { - ReadLogEntry readLogEntry; - while (!shouldStop && (readLogEntry = logReader.readNext()) != null) { - long entryOffset = readLogEntry.getOffset(); - LogEntry logEntry = readLogEntry.getLogEntry(); - OperationBatch batch = extractOperations(logEntry.getOperationBatch(), types); - if (batch.getOperationCount() == 0) { - continue; - } - this.batchSender.asyncSendWithRetry( - "", queueId, batchSnapshotId, entryOffset, batch); - replayCount++; - } - } - logger.info("replay DML records finished. total replayed [{}] records", replayCount); - return batchSnapshotId; - } - - private OperationBatch extractOperations(OperationBatch input, List types) { - boolean hasOtherType = false; - for (int i = 0; i < input.getOperationCount(); ++i) { - OperationBlob blob = input.getOperationBlob(i); - OperationType opType = blob.getOperationType(); - if (!types.contains(opType)) { - hasOtherType = true; - break; - } - } - if (!hasOtherType) { - return input; - } - OperationBatch.Builder batchBuilder = OperationBatch.newBuilder(); - batchBuilder.setLatestSnapshotId(input.getLatestSnapshotId()); - for (int i = 0; i < input.getOperationCount(); ++i) { - OperationBlob blob = input.getOperationBlob(i); - OperationType opType = blob.getOperationType(); - if (types.contains(opType)) { - batchBuilder.addOperationBlob(blob); - } - } - return batchBuilder.build(); - } - - public int getQueueId() { - return queueId; - } - - @Override - public void initMetrics() { - this.totalProcessed = 0L; - this.lastUpdateTime = System.nanoTime(); - this.lastUpdateProcessed = 0L; - this.walBlockTimeNano = 0L; - this.storeBlockTimeNano = 0L; - this.ingestorRejectCount = new AtomicLong(0L); - this.lastUpdateStoreBlockTimeNano = 0L; - this.walBlockPerSecondMs = 0L; - this.lastUpdateStoreBlockTimeNano = 0L; - this.storeBlockPerSecondMs = 0L; - } - - private void updateMetrics() { - long currentTime = System.nanoTime(); - long processed = this.totalProcessed; - long interval = currentTime - this.lastUpdateTime; - this.writeRecordsPerSecond = 1000000000 * (processed - this.lastUpdateProcessed) / interval; - long walBlockTime = this.walBlockTimeNano; - this.walBlockPerSecondMs = - 1000 * (walBlockTime - this.lastUpdateWalBlockTimeNano) / interval; - long storeBlockTime = this.storeBlockTimeNano; - this.storeBlockPerSecondMs = - 1000 * (storeBlockTime - this.lastUpdateStoreBlockTimeNano) / interval; - - this.lastUpdateStoreBlockTimeNano = storeBlockTime; - this.lastUpdateWalBlockTimeNano = walBlockTime; - this.lastUpdateProcessed = processed; - this.lastUpdateTime = currentTime; - } - - @Override - public Map getMetrics() { - return new HashMap<>() { - { - put(WRITE_RECORDS_PER_SECOND, String.valueOf(writeRecordsPerSecond)); - put(WRITE_RECORDS_TOTAL, String.valueOf(totalProcessed)); - put(WAL_BLOCK_PER_SECOND_MS, String.valueOf(walBlockPerSecondMs)); - put(STORE_BLOCK_PER_SECOND_MS, String.valueOf(storeBlockPerSecondMs)); - put(INGESTOR_REJECT_COUNT, String.valueOf(ingestorRejectCount)); - put(INGEST_BUFFER_TASKS_COUNT, String.valueOf(ingestBuffer.size())); - } - }; - } - - @Override - public String[] getMetricKeys() { - return new String[] { - WRITE_RECORDS_PER_SECOND, - WRITE_RECORDS_TOTAL, - WAL_BLOCK_PER_SECOND_MS, - STORE_BLOCK_PER_SECOND_MS, - INGESTOR_REJECT_COUNT, - INGEST_BUFFER_TASKS_COUNT - }; - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressClient.java deleted file mode 100644 index a4c5a32f0abd..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressClient.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.rpc.RpcClient; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsRequest; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsResponse; -import com.alibaba.graphscope.proto.groot.IngestProgressGrpc; - -import io.grpc.ManagedChannel; - -import java.util.List; - -/** ingestor -> coordinator */ -public class IngestProgressClient extends RpcClient { - - private final IngestProgressGrpc.IngestProgressBlockingStub stub; - - public IngestProgressClient(ManagedChannel channel) { - super(channel); - this.stub = IngestProgressGrpc.newBlockingStub(this.channel); - } - - public IngestProgressClient(IngestProgressGrpc.IngestProgressBlockingStub stub) { - super((ManagedChannel) stub.getChannel()); - this.stub = stub; - } - - public List getTailOffsets(List queueIds) { - GetTailOffsetsRequest req = - GetTailOffsetsRequest.newBuilder().addAllQueueId(queueIds).build(); - GetTailOffsetsResponse tailOffsetsResponse = stub.getTailOffsets(req); - return tailOffsetsResponse.getOffsetsList(); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressFetcher.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressFetcher.java deleted file mode 100644 index 13db159a6985..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestProgressFetcher.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import java.util.List; - -public interface IngestProgressFetcher { - List getTailOffsets(List queueIds); -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestService.java deleted file mode 100644 index 5ca4982efb56..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/IngestService.java +++ /dev/null @@ -1,356 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.common.RoleType; -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.IngestorConfig; -import com.alibaba.graphscope.groot.common.util.ThreadFactoryUtils; -import com.alibaba.graphscope.groot.discovery.GrootNode; -import com.alibaba.graphscope.groot.discovery.NodeDiscovery; -import com.alibaba.graphscope.groot.meta.MetaService; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.operation.OperationBlob; -import com.alibaba.graphscope.groot.wal.LogService; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -public class IngestService implements NodeDiscovery.Listener { - private static final Logger logger = LoggerFactory.getLogger(IngestService.class); - - public static final OperationBatch MARKER_BATCH = - OperationBatch.newBuilder() - .addOperationBlob(OperationBlob.MARKER_OPERATION_BLOB) - .build(); - private final Configs configs; - private final NodeDiscovery discovery; - private final MetaService metaService; - private final LogService logService; - private final IngestProgressFetcher ingestProgressFetcher; - private final StoreWriter storeWriter; - private final MetricsCollector metricsCollector; - - private final int ingestorId; - private List queueIds; - private Map queueToProcessor; - private AtomicLong ingestSnapshotId; - - private volatile boolean storeNodeReady; - private ScheduledExecutorService scheduler; - private ExecutorService singleThreadExecutor; - private volatile boolean started = false; - private final int storeNodeCount; - - private final Set availableNodes; - - public IngestService( - Configs configs, - NodeDiscovery discovery, - MetaService metaService, - LogService logService, - IngestProgressFetcher ingestProgressFetcher, - StoreWriter storeWriter, - MetricsCollector metricsCollector) { - this.configs = configs; - this.discovery = discovery; - this.metaService = metaService; - this.logService = logService; - this.ingestProgressFetcher = ingestProgressFetcher; - this.storeWriter = storeWriter; - this.metricsCollector = metricsCollector; - - this.ingestorId = CommonConfig.NODE_IDX.get(configs); - this.storeNodeCount = CommonConfig.STORE_NODE_COUNT.get(configs); - this.availableNodes = new HashSet<>(); - } - - public void start() { - this.ingestSnapshotId = new AtomicLong(-1L); - this.queueIds = this.metaService.getQueueIdsForIngestor(this.ingestorId); - this.queueToProcessor = new HashMap<>(this.queueIds.size()); - for (int queueId : queueIds) { - BatchSender batchSender = - new BatchSender( - this.configs, - this.metaService, - this.storeWriter, - this.metricsCollector); - this.queueToProcessor.put( - queueId, - makeIngestProcessor( - this.configs, - this.logService, - batchSender, - queueId, - this.ingestSnapshotId, - this.metricsCollector)); - } - this.storeNodeReady = false; - this.discovery.addListener(this); - this.singleThreadExecutor = - new ThreadPoolExecutor( - 1, - 1, - 0L, - TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>(), - ThreadFactoryUtils.daemonThreadFactoryWithLogExceptionHandler( - "ingest-single-executor", logger)); - this.scheduler = - Executors.newSingleThreadScheduledExecutor( - ThreadFactoryUtils.daemonThreadFactoryWithLogExceptionHandler( - "ingest-try-start", logger)); - - long delay = IngestorConfig.INGESTOR_CHECK_PROCESSOR_INTERVAL_MS.get(configs); - this.scheduler.scheduleWithFixedDelay( - this::tryStartProcessors, 2000, delay, TimeUnit.MILLISECONDS); - this.started = true; - logger.info("IngestService started"); - } - - public IngestProcessor makeIngestProcessor( - Configs configs, - LogService logService, - BatchSender batchSender, - int queueId, - AtomicLong ingestSnapshotId, - MetricsCollector metricsCollector) { - return new IngestProcessor( - configs, logService, batchSender, queueId, ingestSnapshotId, metricsCollector); - } - - public void stop() { - this.started = false; - this.discovery.removeListener(this); - if (this.scheduler != null) { - this.scheduler.shutdown(); - try { - this.scheduler.awaitTermination(3000L, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - // Ignore - } - this.scheduler = null; - } - stopProcessors(); - if (this.singleThreadExecutor != null) { - this.singleThreadExecutor.shutdown(); - try { - this.singleThreadExecutor.awaitTermination(3000L, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - // Ignore - } - this.singleThreadExecutor = null; - } - logger.debug("IngestService stopped"); - } - - private void checkStarted() { - if (!started) { - throw new IllegalStateException("IngestService not started yet"); - } - } - - public void ingestBatch( - String requestId, int queueId, OperationBatch operationBatch, IngestCallback callback) { - checkStarted(); - this.queueToProcessor.get(queueId).ingestBatch(requestId, operationBatch, callback); - } - - public List replayDMLRecordsFrom(long offset, long timestamp) throws IOException { - List ids = new ArrayList<>(); - for (IngestProcessor processor : queueToProcessor.values()) { - long snapshotId = processor.replayDMLRecordsFrom(offset, timestamp); - ids.add(snapshotId); - } - return ids; - } - - /** - * This method will update writeSnapshotId and returns the previous value. - * - *

SnapshotManager periodically increase the writeSnapshotId and call this method to update - * the writeSnapshotId for each Ingestor. - * - * @param snapshotId - * @return - */ - public synchronized void advanceIngestSnapshotId( - long snapshotId, CompletionCallback callback) { - checkStarted(); - long previousSnapshotId = this.ingestSnapshotId.getAndUpdate(x -> Math.max(x, snapshotId)); - if (previousSnapshotId >= snapshotId) { - throw new IllegalStateException( - "current ingestSnapshotId [" - + previousSnapshotId - + "], cannot update to [" - + snapshotId - + "]"); - } - AtomicInteger counter = new AtomicInteger(this.queueToProcessor.size()); - AtomicBoolean finished = new AtomicBoolean(false); - for (IngestProcessor processor : this.queueToProcessor.values()) { - int queue = processor.getQueueId(); - try { - processor.ingestBatch( - "marker", - MARKER_BATCH, - new IngestCallback() { - @Override - public void onSuccess(long snapshotId) { - if (finished.get()) { - return; - } - if (counter.decrementAndGet() == 0) { - callback.onCompleted(previousSnapshotId); - } - } - - @Override - public void onFailure(Exception e) { - if (finished.getAndSet(true)) { - return; - } - logger.warn( - "ingest marker failed. queue#{}, snapshotId {}", - queue, - snapshotId, - e); - callback.onError(e); - } - }); - } catch (IllegalStateException e) { - if (finished.getAndSet(true)) { - return; - } - logger.warn( - "ingest marker failed. queue#{}, snapshotId {}, {}", - queue, - snapshotId, - e.getMessage()); - callback.onError(e); - } catch (Exception e) { - if (finished.getAndSet(true)) { - return; - } - logger.warn("ingest marker failed. queue#{}, snapshotId {}", queue, snapshotId, e); - callback.onError(e); - } - } - } - - private void startProcessors() { - this.singleThreadExecutor.execute( - () -> { - if (isProcessorStarted()) { - return; - } - for (IngestProcessor processor : this.queueToProcessor.values()) { - processor.stop(); - } - List tailOffsets = - this.ingestProgressFetcher.getTailOffsets(this.queueIds); - for (int i = 0; i < this.queueIds.size(); i++) { - int queueId = this.queueIds.get(i); - long offset = tailOffsets.get(i); - this.queueToProcessor.get(queueId).setTailOffset(offset); - } - for (IngestProcessor processor : this.queueToProcessor.values()) { - processor.start(); - } - logger.info("processors started"); - }); - } - - private boolean isProcessorStarted() { - for (IngestProcessor processor : this.queueToProcessor.values()) { - if (!processor.isStarted()) { - return false; - } - } - return true; - } - - private void stopProcessors() { - if (this.singleThreadExecutor == null) { - logger.warn("no executor for stop processors, ignore"); - return; - } - this.singleThreadExecutor.execute( - () -> { - if (isProcessorStarted()) { - for (IngestProcessor processor : this.queueToProcessor.values()) { - processor.stop(); - } - logger.info("processors stopped"); - } - }); - } - - private void graphNodesReady() { - logger.info("Store ready"); - this.storeNodeReady = true; - } - - private void graphNodesLost() { - logger.info("Store lost"); - this.storeNodeReady = false; - stopProcessors(); - } - - private void tryStartProcessors() { - try { - if (this.storeNodeReady) { - startProcessors(); - } else { - logger.warn("Store node is not ready when trying to start processors"); - } - } catch (Exception e) { - logger.error("tryStartProcessors failed, ignore", e); - } - } - - @Override - public void nodesJoin(RoleType role, Map nodes) { - if (role == RoleType.STORE) { - this.availableNodes.addAll(nodes.keySet()); - if (this.availableNodes.size() == storeNodeCount) { - graphNodesReady(); - } - } - } - - @Override - public void nodesLeft(RoleType role, Map nodes) { - if (role != RoleType.STORE) { - this.availableNodes.removeAll(nodes.keySet()); - graphNodesLost(); - } - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/RemoteIngestProgressFetcher.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/RemoteIngestProgressFetcher.java deleted file mode 100644 index 968c3588e450..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/RemoteIngestProgressFetcher.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.common.RoleType; -import com.alibaba.graphscope.groot.rpc.ChannelManager; -import com.alibaba.graphscope.groot.rpc.RoleClients; - -import java.util.List; - -public class RemoteIngestProgressFetcher extends RoleClients - implements IngestProgressFetcher { - - public RemoteIngestProgressFetcher(ChannelManager channelManager) { - super(channelManager, RoleType.COORDINATOR, IngestProgressClient::new); - } - - @Override - public List getTailOffsets(List queueIds) { - return getClient(0).getTailOffsets(queueIds); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClient.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClient.java deleted file mode 100644 index 6a86449a8866..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClient.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; -import com.alibaba.graphscope.groot.rpc.RpcClient; -import com.alibaba.graphscope.proto.groot.StoreWriteGrpc; -import com.alibaba.graphscope.proto.groot.WriteStoreRequest; -import com.alibaba.graphscope.proto.groot.WriteStoreRequest.Builder; -import com.alibaba.graphscope.proto.groot.WriteStoreResponse; - -import io.grpc.ManagedChannel; -import io.grpc.stub.StreamObserver; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** ingestor -> store */ -public class StoreWriteClient extends RpcClient { - private static final Logger logger = LoggerFactory.getLogger(StoreWriteClient.class); - - private final StoreWriteGrpc.StoreWriteStub stub; - - public StoreWriteClient(ManagedChannel channel) { - super(channel); - this.stub = StoreWriteGrpc.newStub(channel); - } - - public StoreWriteClient(StoreWriteGrpc.StoreWriteStub stub) { - super((ManagedChannel) stub.getChannel()); - this.stub = stub; - } - - public void writeStore( - List storeDataBatches, CompletionCallback callback) { - Builder builder = WriteStoreRequest.newBuilder(); - for (StoreDataBatch storeDataBatch : storeDataBatches) { - builder.addDataBatches(storeDataBatch.toProto()); - } - WriteStoreRequest req = builder.build(); - stub.writeStore( - req, - new StreamObserver() { - @Override - public void onNext(WriteStoreResponse writeStoreResponse) { - boolean success = writeStoreResponse.getSuccess(); - if (success) { - callback.onCompleted(req.getSerializedSize()); - } else { - onError(new RuntimeException("store buffer is full")); - } - } - - @Override - public void onError(Throwable throwable) { - callback.onError(throwable); - } - - @Override - public void onCompleted() {} - }); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClients.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClients.java deleted file mode 100644 index 0ab8c452bce7..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriteClients.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.common.RoleType; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; -import com.alibaba.graphscope.groot.rpc.ChannelManager; -import com.alibaba.graphscope.groot.rpc.RoleClients; - -import io.grpc.ManagedChannel; - -import java.util.List; -import java.util.function.Function; - -public class StoreWriteClients extends RoleClients implements StoreWriter { - - public StoreWriteClients( - ChannelManager channelManager, - RoleType targetRole, - Function clientBuilder) { - super(channelManager, targetRole, clientBuilder); - } - - @Override - public void write( - int storeId, - List storeDataBatches, - CompletionCallback callback) { - this.getClient(storeId).writeStore(storeDataBatches, callback); - } -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriter.java deleted file mode 100644 index 0e946f02e977..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/ingestor/StoreWriter.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.ingestor; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; - -import java.util.List; - -public interface StoreWriter { - void write(int storeId, List batch, CompletionCallback callback); -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/DefaultMetaService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/DefaultMetaService.java index 34db12022a7b..a3ce8897a4c2 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/DefaultMetaService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/DefaultMetaService.java @@ -34,7 +34,7 @@ public class DefaultMetaService implements MetaService { public DefaultMetaService(Configs configs) { this.partitionCount = CommonConfig.PARTITION_COUNT.get(configs); - this.queueCount = CommonConfig.INGESTOR_QUEUE_COUNT.get(configs); + this.queueCount = 1; this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); this.kafkaServers = KafkaConfig.KAFKA_SERVERS.get(configs); this.kafkaTopicName = KafkaConfig.KAKFA_TOPIC.get(configs); @@ -95,16 +95,6 @@ public int getQueueCount() { return this.queueCount; } - @Override - public List getQueueIdsForIngestor(int ingestorId) { - return List.of(ingestorId); - } - - @Override - public int getIngestorIdForQueue(int queueId) { - return queueId; - } - @Override public int getStoreCount() { return this.storeCount; diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/FileMetaStore.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/FileMetaStore.java similarity index 93% rename from interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/FileMetaStore.java rename to interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/FileMetaStore.java index 8dcd796682c3..bdf850a534d5 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/coordinator/FileMetaStore.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/FileMetaStore.java @@ -11,11 +11,7 @@ * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.graphscope.groot.coordinator; - -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.CoordinatorConfig; -import com.alibaba.graphscope.groot.meta.MetaStore; +package com.alibaba.graphscope.groot.meta; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +38,8 @@ public class FileMetaStore implements MetaStore { private final String workingDir; private final Map pathToSuffix; - public FileMetaStore(Configs configs) { - this.workingDir = CoordinatorConfig.FILE_META_STORE_PATH.get(configs); + public FileMetaStore(String metaPath) { + this.workingDir = metaPath; boolean ret = new File(this.workingDir).mkdirs(); this.pathToSuffix = new ConcurrentHashMap<>(); } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/MetaService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/MetaService.java index b3c239915706..8bda96571e0c 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/MetaService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/meta/MetaService.java @@ -28,10 +28,6 @@ public interface MetaService { int getQueueCount(); - List getQueueIdsForIngestor(int ingestorId); - - int getIngestorIdForQueue(int queueId); - int getStoreCount(); String getLoggerServers(); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/metrics/MetricsAggregator.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/metrics/MetricsAggregator.java index dfb87c2626bc..9d662bedf049 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/metrics/MetricsAggregator.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/metrics/MetricsAggregator.java @@ -31,21 +31,18 @@ public class MetricsAggregator { private final ObjectMapper objectMapper; private final int frontendCount; - private final int ingestorCount; private final int storeCount; public MetricsAggregator( Configs configs, RoleClients frontendMetricsCollectClients, - RoleClients ingestorMetricsCollectClients, + // RoleClients ingestorMetricsCollectClients, RoleClients storeMetricsCollectClients) { this.roleToClients.put(RoleType.FRONTEND, frontendMetricsCollectClients); - this.roleToClients.put(RoleType.INGESTOR, ingestorMetricsCollectClients); this.roleToClients.put(RoleType.STORE, storeMetricsCollectClients); this.objectMapper = new ObjectMapper(); this.frontendCount = CommonConfig.FRONTEND_NODE_COUNT.get(configs); - this.ingestorCount = CommonConfig.INGESTOR_NODE_COUNT.get(configs); this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); } @@ -60,10 +57,6 @@ public void aggregateMetricsJson(String roleNames, CompletionCallback ca totalNode += this.frontendCount; roleTypeToCount.put(roleType, this.frontendCount); break; - case INGESTOR: - totalNode += this.ingestorCount; - roleTypeToCount.put(roleType, this.ingestorCount); - break; case STORE: totalNode += this.storeCount; roleTypeToCount.put(roleType, this.storeCount); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/KafkaProcessor.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/KafkaProcessor.java new file mode 100644 index 000000000000..d4dbe73ed9dc --- /dev/null +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/KafkaProcessor.java @@ -0,0 +1,266 @@ +package com.alibaba.graphscope.groot.store; + +import com.alibaba.graphscope.groot.Utils; +import com.alibaba.graphscope.groot.common.config.CommonConfig; +import com.alibaba.graphscope.groot.common.config.Configs; +import com.alibaba.graphscope.groot.common.config.StoreConfig; +import com.alibaba.graphscope.groot.common.exception.GrootException; +import com.alibaba.graphscope.groot.common.util.PartitionUtils; +import com.alibaba.graphscope.groot.common.util.ThreadFactoryUtils; +import com.alibaba.graphscope.groot.meta.FileMetaStore; +import com.alibaba.graphscope.groot.meta.MetaService; +import com.alibaba.graphscope.groot.meta.MetaStore; +import com.alibaba.graphscope.groot.operation.OperationBatch; +import com.alibaba.graphscope.groot.operation.OperationBlob; +import com.alibaba.graphscope.groot.operation.OperationType; +import com.alibaba.graphscope.groot.operation.StoreDataBatch; +import com.alibaba.graphscope.groot.wal.LogEntry; +import com.alibaba.graphscope.groot.wal.LogReader; +import com.alibaba.graphscope.groot.wal.LogService; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +public class KafkaProcessor { + private static final Logger logger = LoggerFactory.getLogger(KafkaProcessor.class); + + private final LogService logService; + + private AtomicReference> queueOffsetsRef; + private final MetaStore metaStore; + private final MetaService metaService; + + private final ObjectMapper objectMapper; + private ScheduledExecutorService persistOffsetsScheduler; + private Thread pollThread; + + private final boolean isSecondary; + + private final WriterAgent writerAgent; + public static final String QUEUE_OFFSETS_PATH = "queue_offsets"; + public static final int QUEUE_COUNT = 1; + + public static int storeId = 0; + private volatile boolean shouldStop = true; + List typesDDL; + + public KafkaProcessor( + Configs configs, + MetaService metaService, + WriterAgent writerAgent, + LogService logService) { + this.metaService = metaService; + this.writerAgent = writerAgent; + this.logService = logService; + + String metaPath = StoreConfig.STORE_DATA_PATH.get(configs) + "/meta"; + this.metaStore = new FileMetaStore(metaPath); + this.objectMapper = new ObjectMapper(); + this.isSecondary = CommonConfig.SECONDARY_INSTANCE_ENABLED.get(configs); + + storeId = CommonConfig.NODE_IDX.get(configs); + } + + public void start() { + try { + recover(); + } catch (IOException e) { + throw new GrootException(e); + } + + this.persistOffsetsScheduler = + Executors.newSingleThreadScheduledExecutor( + ThreadFactoryUtils.daemonThreadFactoryWithLogExceptionHandler( + "persist-offsets-scheduler", logger)); + this.persistOffsetsScheduler.scheduleWithFixedDelay( + () -> { + try { + updateQueueOffsets(); + } catch (Exception e) { + logger.error("error in updateQueueOffsets, ignore", e); + } + }, + 3000, + 3000, + TimeUnit.MILLISECONDS); + this.shouldStop = false; + this.pollThread = new Thread(this::pollBatches); + this.pollThread.setName("store-kafka-poller"); + this.pollThread.setDaemon(true); + this.pollThread.start(); + } + + public void stop() { + this.shouldStop = true; + if (this.persistOffsetsScheduler != null) { + this.persistOffsetsScheduler.shutdown(); + try { + this.persistOffsetsScheduler.awaitTermination(3000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Ignore + } + this.persistOffsetsScheduler = null; + } + + if (this.pollThread != null) { + this.pollThread.interrupt(); + try { + this.pollThread.join(3000); + } catch (InterruptedException e) { + // Do nothing + } + this.pollThread = null; + } + } + + public void recover() throws IOException { + List offsets = new ArrayList<>(QUEUE_COUNT); + if (!this.metaStore.exists(QUEUE_OFFSETS_PATH)) { + for (int i = 0; i < QUEUE_COUNT; i++) { + offsets.add(-1L); + } + byte[] b = this.objectMapper.writeValueAsBytes(offsets); + this.metaStore.write(QUEUE_OFFSETS_PATH, b); + } else { + byte[] offsetBytes = this.metaStore.read(QUEUE_OFFSETS_PATH); + offsets = objectMapper.readValue(offsetBytes, new TypeReference<>() {}); + } + queueOffsetsRef = new AtomicReference<>(offsets); + logger.info("[STORE] recovered queue offsets {}", offsets); + if (offsets.size() != QUEUE_COUNT) { + String msg = + String.format( + "recovered queueCount %d, expect %d", offsets.size(), QUEUE_COUNT); + throw new IllegalStateException(msg); + } + } + + private void updateQueueOffsets() throws IOException { + List queueOffsets = this.queueOffsetsRef.get(); + List newQueueOffsets = new ArrayList<>(queueOffsets); + boolean changed = false; + List consumedOffsets = writerAgent.getConsumedQueueOffsets(); + for (int qId = 0; qId < queueOffsets.size(); qId++) { + long minOffset = Long.MAX_VALUE; + minOffset = Math.min(consumedOffsets.get(qId), minOffset); + if (minOffset != Long.MAX_VALUE && minOffset > newQueueOffsets.get(qId)) { + newQueueOffsets.set(qId, minOffset); + changed = true; + } + } + if (changed) { + persistObject(newQueueOffsets, QUEUE_OFFSETS_PATH); + this.queueOffsetsRef.set(newQueueOffsets); + } + } + + private void persistObject(Object value, String path) throws IOException { + if (isSecondary) { + return; + } + byte[] b = objectMapper.writeValueAsBytes(value); + metaStore.write(path, b); + } + + public void pollBatches() { + typesDDL = prepareDDLTypes(); + try { + replayWAL(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + try (LogReader reader = logService.createReader(storeId, -1)) { + while (!shouldStop) { + ConsumerRecords records = reader.getLatestUpdates(); + for (ConsumerRecord record : records) { + processRecord(record); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void processRecord(ConsumerRecord record) { + int partitionCount = metaService.getPartitionCount(); + long offset = record.offset(); + LogEntry logEntry = record.value(); + OperationBatch operationBatch = logEntry.getOperationBatch(); + if (isSecondary) { // only catch up the schema updates + operationBatch = Utils.extractOperations(operationBatch, typesDDL); + } + if (operationBatch.getOperationCount() == 0) { + return; + } + long snapshotId = logEntry.getSnapshotId(); + StoreDataBatch.Builder builder = + StoreDataBatch.newBuilder() + .requestId("") + .queueId(storeId) + .snapshotId(snapshotId) + .offset(offset); + for (OperationBlob operationBlob : operationBatch) { + long partitionKey = operationBlob.getPartitionKey(); + if (partitionKey == -1L) { + // replicate to all store node + builder.addOperation(-1, operationBlob); + } else { + int partitionId = + PartitionUtils.getPartitionIdFromKey(partitionKey, partitionCount); + int batchStoreId = metaService.getStoreIdByPartition(partitionId); + if (batchStoreId == storeId) { + builder.addOperation(partitionId, operationBlob); + } else { + logger.error("Should not happen: {} {}", partitionId, operationBlob.toProto()); + } + } + } + try { + writerAgent.writeStore(builder.build()); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public void replayWAL() throws IOException { + long queueOffset = queueOffsetsRef.get().get(0); + long replayFrom = queueOffset + 1; + logger.info("replay WAL of queue#[{}] from offset [{}]", storeId, replayFrom); + int replayCount = 0; + try (LogReader logReader = this.logService.createReader(storeId, replayFrom)) { + ConsumerRecord record; + while ((record = logReader.readNextRecord()) != null) { + processRecord(record); + replayCount++; + } + } + logger.info("replayWAL finished. total replayed [{}] records", replayCount); + } + + private List prepareDDLTypes() { + List types = new ArrayList<>(); + types.add(OperationType.CREATE_VERTEX_TYPE); + types.add(OperationType.CREATE_EDGE_TYPE); + types.add(OperationType.ADD_EDGE_KIND); + types.add(OperationType.DROP_VERTEX_TYPE); + types.add(OperationType.DROP_EDGE_TYPE); + types.add(OperationType.REMOVE_EDGE_KIND); + types.add(OperationType.PREPARE_DATA_LOAD); + types.add(OperationType.COMMIT_DATA_LOAD); + types.add(OperationType.MARKER); // For advance ID + return types; + } +} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/WriterAgent.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/WriterAgent.java index e47079a3265f..2454021ba908 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/WriterAgent.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/store/WriterAgent.java @@ -26,14 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.*; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -53,23 +47,22 @@ public class WriterAgent implements MetricsAgent { public static final String STORE_WRITE_TOTAL = "store.write.total"; public static final String BUFFER_WRITE_PER_SECOND_MS = "buffer.write.per.second.ms"; - private Configs configs; - private int storeId; - private int queueCount; - private StoreService storeService; - private MetaService metaService; - private SnapshotCommitter snapshotCommitter; + private final Configs configs; + private final int storeId; + private final int queueCount; + private final StoreService storeService; + private final MetaService metaService; + private final SnapshotCommitter snapshotCommitter; private volatile boolean shouldStop = true; private SnapshotSortQueue bufferQueue; private volatile long lastCommitSnapshotId; private volatile long consumeSnapshotId; private volatile long consumeDdlSnapshotId; - private AtomicReference availSnapshotInfoRef; + private final AtomicReference availSnapshotInfoRef; private ExecutorService commitExecutor; private List consumedQueueOffsets; private Thread consumeThread; - private volatile long lastUpdateTime; private volatile long totalWrite; private volatile long writePerSecond; @@ -95,7 +88,7 @@ public WriterAgent( this.snapshotCommitter = snapshotCommitter; this.availSnapshotInfoRef = new AtomicReference<>(); initMetrics(); - metricsCollector.register(this, () -> updateMetrics()); + metricsCollector.register(this, this::updateMetrics); } /** should be called once, before start */ @@ -115,11 +108,6 @@ public void start() { this.consumedQueueOffsets.add(-1L); } - this.consumeThread = new Thread(() -> processBatches()); - this.consumeThread.setName("store-consume"); - this.consumeThread.setDaemon(true); - this.consumeThread.start(); - this.commitExecutor = new ThreadPoolExecutor( 1, @@ -129,6 +117,11 @@ public void start() { new LinkedBlockingQueue<>(), ThreadFactoryUtils.daemonThreadFactoryWithLogExceptionHandler( "writer-agent-commit", logger)); + + this.consumeThread = new Thread(this::processBatches); + this.consumeThread.setName("store-consume"); + this.consumeThread.setDaemon(true); + this.consumeThread.start(); logger.info("WriterAgent started"); } @@ -152,6 +145,7 @@ public void stop() { } this.commitExecutor = null; } + logger.debug("WriterAgent stopped"); } @@ -163,9 +157,11 @@ public void stop() { * @return True if offer success, otherwise False */ public boolean writeStore(StoreDataBatch storeDataBatch) throws InterruptedException { - int queueId = storeDataBatch.getQueueId(); + // logger.info("writeStore {}", storeDataBatch.toProto()); + // int queueId = storeDataBatch.getQueueId(); long beforeOfferTime = System.nanoTime(); - boolean suc = this.bufferQueue.offerQueue(queueId, storeDataBatch); + boolean suc = this.bufferQueue.offerQueue(0, storeDataBatch); + logger.debug("Buffer queue: {}, {}", suc, this.bufferQueue.innerQueueSizes()); long afterOfferTime = System.nanoTime(); this.bufferWritePerSecondMetric.add(afterOfferTime - beforeOfferTime); return suc; @@ -187,45 +183,28 @@ public boolean writeStore2(List storeDataBatches) throws Interru private void processBatches() { while (!shouldStop) { try { - long beforePollNano = System.nanoTime(); - StoreDataBatch storeDataBatch = this.bufferQueue.poll(); - long afterPollNano = System.nanoTime(); - long pollNano = afterPollNano - beforePollNano; - this.totalPollLatencyNano += pollNano; - this.maxPollLatencyNano.updateAndGet( - curMax -> (pollNano > curMax) ? pollNano : curMax); - if (storeDataBatch == null) { + StoreDataBatch batch = this.bufferQueue.poll(); + if (batch == null) { continue; } - long batchSnapshotId = storeDataBatch.getSnapshotId(); + long batchSnapshotId = batch.getSnapshotId(); logger.debug("polled one batch [" + batchSnapshotId + "]"); - boolean hasDdl = writeEngineWithRetry(storeDataBatch); - int writeCount = storeDataBatch.getSize(); - this.totalWrite += writeCount; + boolean hasDdl = writeEngineWithRetry(batch); + this.totalWrite += batch.getSize(); if (this.consumeSnapshotId < batchSnapshotId) { - SnapshotInfo availSnapshotInfo = this.availSnapshotInfoRef.get(); - long availDdlSnapshotId = availSnapshotInfo.getDdlSnapshotId(); - if (availDdlSnapshotId < this.consumeDdlSnapshotId) { - availDdlSnapshotId = this.consumeDdlSnapshotId; - } - long prevSnapshotId = batchSnapshotId - 1; - long availSnapshotId = availSnapshotInfo.getSnapshotId(); - if (availSnapshotId < prevSnapshotId) { - availSnapshotId = prevSnapshotId; - } + SnapshotInfo availSInfo = this.availSnapshotInfoRef.get(); + long availSI = Math.max(availSInfo.getSnapshotId(), batchSnapshotId - 1); + long availDdlSI = Math.max(availSInfo.getDdlSnapshotId(), consumeDdlSnapshotId); this.consumeSnapshotId = batchSnapshotId; - this.availSnapshotInfoRef.set( - new SnapshotInfo(availSnapshotId, availDdlSnapshotId)); - this.commitExecutor.execute(() -> asyncCommit()); + this.availSnapshotInfoRef.set(new SnapshotInfo(availSI, availDdlSI)); + this.commitExecutor.execute(this::asyncCommit); } - if (hasDdl) { this.consumeDdlSnapshotId = batchSnapshotId; } - - int queueId = storeDataBatch.getQueueId(); - long offset = storeDataBatch.getOffset(); - this.consumedQueueOffsets.set(queueId, offset); + // this.consumedQueueOffsets.set(batch.getQueueId(), + // batch.getOffset()); + this.consumedQueueOffsets.set(0, batch.getOffset()); } catch (InterruptedException e) { logger.error("processBatches interrupted"); } catch (Exception e) { @@ -241,22 +220,15 @@ private void asyncCommit() { long ddlSnapshotId = snapshotInfo.getDdlSnapshotId(); List queueOffsets = new ArrayList<>(this.consumedQueueOffsets); try { - logger.debug( - "commit snapshotId [" - + availSnapshotId - + "], last DDL snapshotId [" - + ddlSnapshotId - + "]"); + // logger.info("commit SI {}, last DDL SI {}", availSnapshotId, ddlSnapshotId); this.snapshotCommitter.commitSnapshotId( - this.storeId, availSnapshotId, ddlSnapshotId, queueOffsets); + storeId, availSnapshotId, ddlSnapshotId, queueOffsets); this.lastCommitSnapshotId = availSnapshotId; } catch (Exception e) { logger.warn( - "commit failed. snapshotId [" - + availSnapshotId - + "], queueOffsets [" - + queueOffsets - + "]. will ignore", + "commit failed. SI {}, offset {}. ignored", + availSnapshotId, + queueOffsets, e); } } @@ -267,22 +239,16 @@ private boolean writeEngineWithRetry(StoreDataBatch storeDataBatch) { try { return this.storeService.batchWrite(storeDataBatch); } catch (Exception e) { - logger.error( - "writeEngine failed. queueId [" - + storeDataBatch.getQueueId() - + "], " - + "snapshotId [" - + storeDataBatch.getSnapshotId() - + "], " - + "offset [" - + storeDataBatch.getOffset() - + "]. will retry", - e); + logger.error("writeEngine failed: batch {}.", storeDataBatch.toProto(), e); } } return false; } + public List getConsumedQueueOffsets() { + return consumedQueueOffsets; + } + @Override public void initMetrics() { this.lastUpdateTime = System.nanoTime(); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogReader.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogReader.java index 22885c2aa7c1..bbabb199a1fc 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogReader.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogReader.java @@ -15,6 +15,9 @@ */ package com.alibaba.graphscope.groot.wal; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; + import java.io.IOException; /** @@ -28,5 +31,9 @@ public interface LogReader extends AutoCloseable { */ ReadLogEntry readNext(); + public ConsumerRecord readNextRecord(); + + ConsumerRecords getLatestUpdates(); + void close() throws IOException; } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogService.java index 647ca60d7e57..c5970d74c36d 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogService.java @@ -30,10 +30,9 @@ public interface LogService { /** * Create a writer that can append data to a specific queue of LogService. - * @param queueId * @return */ - LogWriter createWriter(int queueId); + LogWriter createWriter(); /** * Create a reader can read data of specific queue from certain offset. diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogWriter.java index 4c10051ebd5a..f1cc7cc42c88 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogWriter.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/LogWriter.java @@ -29,5 +29,7 @@ public interface LogWriter extends AutoCloseable { */ long append(LogEntry logEntry) throws IOException; + long append(int partition, LogEntry logEntry) throws IOException; + void close() throws IOException; } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogReader.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogReader.java index d4eefed4fa65..ac8b3dcf04c5 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogReader.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogReader.java @@ -57,8 +57,9 @@ public KafkaLogReader( long earliest = getOffset(client, partition, OffsetSpec.earliest()); latest = getOffset(client, partition, OffsetSpec.latest()); - // Get offset from timestamp - if (offset == -1) { + if (offset == -1 && timestamp == -1) { // Seek to end + offset = latest; + } else if (offset == -1) { // Get offset from timestamp offset = getOffset(client, partition, OffsetSpec.forTimestamp(timestamp)); } if (earliest > offset || offset > latest) { @@ -66,6 +67,7 @@ public KafkaLogReader( "invalid offset " + offset + ", hint: [" + earliest + ", " + latest + ")"); } consumer = new KafkaConsumer<>(kafkaConfigs, deSer, deSer); + consumer.assign(List.of(partition)); consumer.seek(partition, offset); nextReadOffset = offset; @@ -108,6 +110,29 @@ public ReadLogEntry readNext() { return new ReadLogEntry(record.offset(), v); } + @Override + public ConsumerRecord readNextRecord() { + if (nextReadOffset == latest) { + return null; + } + while (iterator == null || !iterator.hasNext()) { + ConsumerRecords consumerRecords = + consumer.poll(Duration.ofMillis(100L)); + if (consumerRecords == null || consumerRecords.isEmpty()) { + logger.info("polled nothing from Kafka. nextReadOffset is [{}]", nextReadOffset); + continue; + } + iterator = consumerRecords.iterator(); + } + ConsumerRecord record = iterator.next(); + nextReadOffset = record.offset() + 1; + return record; + } + + public ConsumerRecords getLatestUpdates() { + return consumer.poll(Duration.ofMillis(1000L)); + } + @Override public void close() throws IOException { consumer.close(); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogService.java index 5e453db4dbd2..c490f375101c 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogService.java @@ -39,7 +39,7 @@ public class KafkaLogService implements LogService { private final Configs configs; private final String servers; private final String topic; - private final int queueCount; + private final int storeCount; private final short replicationFactor; private final int maxMessageMb; @@ -49,7 +49,7 @@ public KafkaLogService(Configs configs) { this.configs = configs; this.servers = KafkaConfig.KAFKA_SERVERS.get(configs); this.topic = KafkaConfig.KAKFA_TOPIC.get(configs); - this.queueCount = CommonConfig.INGESTOR_QUEUE_COUNT.get(configs); + this.storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); this.replicationFactor = KafkaConfig.KAFKA_REPLICATION_FACTOR.get(configs); this.maxMessageMb = KafkaConfig.KAFKA_MAX_MESSAGE_MB.get(configs); logger.info("Initialized KafkaLogService"); @@ -58,7 +58,7 @@ public KafkaLogService(Configs configs) { @Override public void init() { AdminClient admin = getAdmin(); - NewTopic newTopic = new NewTopic(this.topic, this.queueCount, this.replicationFactor); + NewTopic newTopic = new NewTopic(this.topic, this.storeCount, this.replicationFactor); Map configs = new HashMap<>(); configs.put("retention.ms", "-1"); configs.put("retention.bytes", "-1"); @@ -92,7 +92,9 @@ public boolean initialized() { } @Override - public LogWriter createWriter(int queueId) { + public LogWriter createWriter() { + while (!initialized()) + ; String customConfigsStr = KafkaConfig.KAFKA_PRODUCER_CUSTOM_CONFIGS.get(configs); Map customConfigs = new HashMap<>(); if (!customConfigsStr.isEmpty()) { @@ -106,11 +108,13 @@ public LogWriter createWriter(int queueId) { } } logger.info("Kafka writer configs {}", customConfigs); - return new KafkaLogWriter(servers, topic, queueId, customConfigs); + return new KafkaLogWriter(servers, topic, customConfigs); } @Override public LogReader createReader(int queueId, long offset) throws IOException { + while (!initialized()) + ; return createReader(queueId, offset, -1); } @@ -145,6 +149,7 @@ private AdminClient getAdmin() { } } } + logger.info("Created AdminClient"); return this.adminClient; } @@ -152,12 +157,12 @@ private AdminClient createAdminWithRetry() throws InterruptedException { Map adminConfig = new HashMap<>(); adminConfig.put("bootstrap.servers", this.servers); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 30; ++i) { try { return AdminClient.create(adminConfig); } catch (Exception e) { logger.warn("Error creating Kafka AdminClient", e); - Thread.sleep(5000); + Thread.sleep(10000); } } throw new RuntimeException("Create Kafka Client failed"); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogWriter.java index 2f51fea09e89..15a4006a2213 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogWriter.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/kafka/KafkaLogWriter.java @@ -38,12 +38,9 @@ public class KafkaLogWriter implements LogWriter { private static final LogEntrySerializer ser = new LogEntrySerializer(); private final Producer producer; private final String topicName; - private final int partitionId; - public KafkaLogWriter( - String servers, String topicName, int partitionId, Map customConfigs) { + public KafkaLogWriter(String servers, String topicName, Map customConfigs) { this.topicName = topicName; - this.partitionId = partitionId; Map producerConfig = new HashMap<>(); producerConfig.put("bootstrap.servers", servers); @@ -57,11 +54,19 @@ public KafkaLogWriter( this.producer = new KafkaProducer<>(producerConfig, ser, ser); } + public long append(int partition, LogEntry logEntry) { + Future future = + producer.send(new ProducerRecord<>(topicName, partition, null, logEntry)); + return waitFuture(future); + } + @Override public long append(LogEntry logEntry) { - Future future = - producer.send( - new ProducerRecord<>(this.topicName, this.partitionId, null, logEntry)); + Future future = producer.send(new ProducerRecord<>(topicName, logEntry)); + return waitFuture(future); + } + + public long waitFuture(Future future) { RecordMetadata recordMetadata; try { recordMetadata = future.get(); diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogReader.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogReader.java deleted file mode 100644 index 584fb6c48623..000000000000 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogReader.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.wal.readonly; - -import com.alibaba.graphscope.groot.wal.LogEntry; -import com.alibaba.graphscope.groot.wal.LogReader; -import com.alibaba.graphscope.groot.wal.ReadLogEntry; -import com.alibaba.graphscope.groot.wal.kafka.LogEntryDeserializer; - -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerRecords; -import org.apache.kafka.clients.consumer.KafkaConsumer; -import org.apache.kafka.common.TopicPartition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.time.Duration; -import java.util.*; - -public class ReadOnlyLogReader implements LogReader { - - private static final Logger logger = LoggerFactory.getLogger(ReadOnlyLogReader.class); - - private static final LogEntryDeserializer deSer = new LogEntryDeserializer(); - private final Consumer consumer; - - public ReadOnlyLogReader(String servers, String topicName, int partitionId) throws IOException { - Map kafkaConfigs = new HashMap<>(); - kafkaConfigs.put("bootstrap.servers", servers); - - TopicPartition partition = new TopicPartition(topicName, partitionId); - - consumer = new KafkaConsumer<>(kafkaConfigs, deSer, deSer); - consumer.assign(List.of(partition)); - consumer.seekToEnd(consumer.assignment()); - logger.info("Created MockLogReader"); - } - - public ConsumerRecords getLatestUpdates() { - ConsumerRecords consumerRecords = - consumer.poll(Duration.ofMillis(1000L)); - return consumerRecords; - } - - @Override - public ReadLogEntry readNext() { - return null; - } - - @Override - public void close() throws IOException {} -} diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogService.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogService.java index 2508f15dbcee..d2885d117dfa 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogService.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogService.java @@ -14,53 +14,17 @@ package com.alibaba.graphscope.groot.wal.readonly; import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.KafkaConfig; -import com.alibaba.graphscope.groot.wal.LogReader; -import com.alibaba.graphscope.groot.wal.LogService; import com.alibaba.graphscope.groot.wal.LogWriter; +import com.alibaba.graphscope.groot.wal.kafka.KafkaLogService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; - -public class ReadOnlyLogService implements LogService { - private static final Logger logger = LoggerFactory.getLogger(ReadOnlyLogService.class); - private final String servers; - private final String topic; +public class ReadOnlyLogService extends KafkaLogService { public ReadOnlyLogService(Configs configs) { - this.servers = KafkaConfig.KAFKA_SERVERS.get(configs); - this.topic = KafkaConfig.KAKFA_TOPIC.get(configs); - logger.info("Initialized MockLogService"); - } - - @Override - public void init() {} - - @Override - public void destroy() {} - - @Override - public boolean initialized() { - return true; + super(configs); } @Override - public LogWriter createWriter(int queueId) { + public LogWriter createWriter() { return new ReadOnlyLogWriter(); } - - @Override - public LogReader createReader(int queueId, long offset) throws IOException { - return createReader(queueId, offset, -1); - } - - @Override - public LogReader createReader(int queueId, long offset, long timestamp) throws IOException { - return new ReadOnlyLogReader(servers, topic, queueId); - } - - @Override - public void deleteBeforeOffset(int queueId, long offset) throws IOException {} } diff --git a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogWriter.java b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogWriter.java index 0c9d860513a5..e92d805b40a5 100644 --- a/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogWriter.java +++ b/interactive_engine/groot-module/src/main/java/com/alibaba/graphscope/groot/wal/readonly/ReadOnlyLogWriter.java @@ -25,6 +25,10 @@ public ReadOnlyLogWriter() {} @Override public long append(LogEntry logEntry) throws IOException { + return append(0, logEntry); + } + + public long append(int partition, LogEntry logEntry) throws IOException { offset += 1; return offset; } diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Coordinator.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Coordinator.java index 9af8b6ccbab7..bd73db9b849b 100644 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Coordinator.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Coordinator.java @@ -18,11 +18,13 @@ import com.alibaba.graphscope.groot.common.RoleType; import com.alibaba.graphscope.groot.common.config.CommonConfig; import com.alibaba.graphscope.groot.common.config.Configs; +import com.alibaba.graphscope.groot.common.config.CoordinatorConfig; import com.alibaba.graphscope.groot.common.exception.GrootException; import com.alibaba.graphscope.groot.coordinator.*; +import com.alibaba.graphscope.groot.coordinator.IngestorWriteClient; import com.alibaba.graphscope.groot.discovery.*; -import com.alibaba.graphscope.groot.frontend.IngestorWriteClient; import com.alibaba.graphscope.groot.meta.DefaultMetaService; +import com.alibaba.graphscope.groot.meta.FileMetaStore; import com.alibaba.graphscope.groot.meta.MetaService; import com.alibaba.graphscope.groot.meta.MetaStore; import com.alibaba.graphscope.groot.rpc.ChannelManager; @@ -42,25 +44,26 @@ public class Coordinator extends NodeBase { private CuratorFramework curator; - private NodeDiscovery discovery; - private SnapshotManager snapshotManager; - private MetaService metaService; - private SchemaManager schemaManager; - private SnapshotNotifier snapshotNotifier; - private RpcServer rpcServer; - private ChannelManager channelManager; - private LogRecycler logRecycler; - private GraphInitializer graphInitializer; - private IdAllocator idAllocator; - private BackupManager backupManager; + private final NodeDiscovery discovery; + private final SnapshotManager snapshotManager; + private final MetaService metaService; + private final SchemaManager schemaManager; + private final SnapshotNotifier snapshotNotifier; + private final RpcServer rpcServer; + private final ChannelManager channelManager; + private final LogRecycler logRecycler; + private final GraphInitializer graphInitializer; + private final IdAllocator idAllocator; + private final BackupManager backupManager; - private GarbageCollectManager garbageCollectManager; + private final GarbageCollectManager garbageCollectManager; public Coordinator(Configs configs) { super(configs); configs = reConfig(configs); LocalNodeProvider localNodeProvider = new LocalNodeProvider(configs); - MetaStore metaStore = new FileMetaStore(configs); + MetaStore metaStore = + new FileMetaStore(CoordinatorConfig.FILE_META_STORE_PATH.get(configs)); if (CommonConfig.DISCOVERY_MODE.get(configs).equalsIgnoreCase("file")) { this.discovery = new FileDiscovery(configs); } else { @@ -76,7 +79,7 @@ public Coordinator(Configs configs) { this.channelManager, RoleType.FRONTEND, FrontendSnapshotClient::new); RoleClients ingestorSnapshotClients = new RoleClients<>( - this.channelManager, RoleType.INGESTOR, IngestorSnapshotClient::new); + this.channelManager, RoleType.FRONTEND, IngestorSnapshotClient::new); WriteSnapshotIdNotifier writeSnapshotIdNotifier = new IngestorWriteSnapshotIdNotifier(configs, ingestorSnapshotClients); @@ -85,7 +88,7 @@ public Coordinator(Configs configs) { new SnapshotManager(configs, metaStore, logService, writeSnapshotIdNotifier); DdlExecutors ddlExecutors = new DdlExecutors(); RoleClients ingestorWriteClients = - new RoleClients<>(this.channelManager, RoleType.INGESTOR, IngestorWriteClient::new); + new RoleClients<>(this.channelManager, RoleType.FRONTEND, IngestorWriteClient::new); DdlWriter ddlWriter = new DdlWriter(ingestorWriteClients); this.metaService = new DefaultMetaService(configs); RoleClients storeSchemaClients = @@ -104,8 +107,6 @@ public Coordinator(Configs configs) { this.snapshotManager, this.schemaManager, frontendSnapshotClients); - IngestProgressService ingestProgressService = - new IngestProgressService(this.snapshotManager); SnapshotCommitService snapshotCommitService = new SnapshotCommitService(this.snapshotManager); SchemaService schemaService = new SchemaService(this.schemaManager); @@ -135,7 +136,6 @@ public Coordinator(Configs configs) { new RpcServer( configs, localNodeProvider, - ingestProgressService, snapshotCommitService, schemaService, idAllocateService, diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Frontend.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Frontend.java index 5c5d994d8f0d..019f9ff97cc4 100644 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Frontend.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Frontend.java @@ -29,6 +29,7 @@ import com.alibaba.graphscope.groot.frontend.write.DefaultEdgeIdGenerator; import com.alibaba.graphscope.groot.frontend.write.EdgeIdGenerator; import com.alibaba.graphscope.groot.frontend.write.GraphWriter; +import com.alibaba.graphscope.groot.frontend.write.KafkaAppender; import com.alibaba.graphscope.groot.meta.DefaultMetaService; import com.alibaba.graphscope.groot.meta.MetaService; import com.alibaba.graphscope.groot.metrics.MetricsAggregator; @@ -41,6 +42,8 @@ import com.alibaba.graphscope.groot.rpc.RoleClients; import com.alibaba.graphscope.groot.rpc.RpcServer; import com.alibaba.graphscope.groot.schema.ddl.DdlExecutors; +import com.alibaba.graphscope.groot.wal.LogService; +import com.alibaba.graphscope.groot.wal.LogServiceFactory; import com.google.common.annotations.VisibleForTesting; import io.grpc.BindableService; @@ -68,6 +71,8 @@ public class Frontend extends NodeBase { private SnapshotCache snapshotCache; + private GraphWriter graphWriter; + public Frontend(Configs configs) { super(configs); configs = reConfig(configs); @@ -86,19 +91,13 @@ public Frontend(Configs configs) { RoleClients frontendMetricsCollectClients = new RoleClients<>( this.channelManager, RoleType.FRONTEND, MetricsCollectClient::new); - RoleClients ingestorMetricsCollectClients = - new RoleClients<>( - this.channelManager, RoleType.INGESTOR, MetricsCollectClient::new); RoleClients storeMetricsCollectClients = new RoleClients<>(this.channelManager, RoleType.STORE, MetricsCollectClient::new); MetricsAggregator metricsAggregator = new MetricsAggregator( - configs, - frontendMetricsCollectClients, - ingestorMetricsCollectClients, - storeMetricsCollectClients); + configs, frontendMetricsCollectClients, storeMetricsCollectClients); - StoreIngestor storeIngestClients = + StoreIngestClients storeIngestClients = new StoreIngestClients(this.channelManager, RoleType.STORE, StoreIngestClient::new); SchemaWriter schemaWriter = new SchemaWriter( @@ -107,7 +106,7 @@ public Frontend(Configs configs) { BatchDdlClient batchDdlClient = new BatchDdlClient(new DdlExecutors(), snapshotCache, schemaWriter); - StoreStateFetcher storeStateClients = + StoreStateClients storeStateClients = new StoreStateClients(this.channelManager, RoleType.STORE, StoreStateClient::new); this.metaService = new DefaultMetaService(configs); @@ -126,22 +125,20 @@ public Frontend(Configs configs) { MetricsCollector metricsCollector = new MetricsCollector(configs); MetricsCollectService metricsCollectService = new MetricsCollectService(metricsCollector); - this.rpcServer = - new RpcServer( - configs, localNodeProvider, frontendSnapshotService, metricsCollectService); GrootDdlService clientDdlService = new GrootDdlService(snapshotCache, batchDdlClient); EdgeIdGenerator edgeIdGenerator = new DefaultEdgeIdGenerator(configs, this.channelManager); - RoleClients ingestorWriteClients = - new RoleClients<>(this.channelManager, RoleType.INGESTOR, IngestorWriteClient::new); - GraphWriter graphWriter = + + LogService logService = LogServiceFactory.makeLogService(configs); + KafkaAppender kafkaAppender = new KafkaAppender(configs, metaService, logService); + this.graphWriter = new GraphWriter( snapshotCache, edgeIdGenerator, this.metaService, - ingestorWriteClients, metricsCollector, + kafkaAppender, configs); WriteSessionGenerator writeSessionGenerator = new WriteSessionGenerator(configs); ClientWriteService clientWriteService = @@ -150,6 +147,19 @@ public Frontend(Configs configs) { RoleClients backupClients = new RoleClients<>(this.channelManager, RoleType.COORDINATOR, BackupClient::new); ClientBackupService clientBackupService = new ClientBackupService(backupClients); + + IngestorSnapshotService ingestorSnapshotService = + new IngestorSnapshotService(kafkaAppender); + IngestorWriteService ingestorWriteService = new IngestorWriteService(kafkaAppender); + this.rpcServer = + new RpcServer( + configs, + localNodeProvider, + frontendSnapshotService, + metricsCollectService, + ingestorSnapshotService, + ingestorWriteService); + this.serviceServer = buildServiceServer( configs, @@ -190,6 +200,7 @@ public void start() { this.curator.start(); } this.metaService.start(); + this.graphWriter.start(); try { this.rpcServer.start(); } catch (IOException e) { diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/GrootGraph.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/GrootGraph.java index ca426f6a3636..f03801e4c735 100644 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/GrootGraph.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/GrootGraph.java @@ -51,9 +51,6 @@ public static void main(String[] args) throws IOException { case FRONTEND: node = new Frontend(conf); break; - case INGESTOR: - node = new Ingestor(conf); - break; case STORE: node = new Store(conf); break; diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Ingestor.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Ingestor.java deleted file mode 100644 index 8f8b5a999d96..000000000000 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Ingestor.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.servers; - -import com.alibaba.graphscope.groot.CuratorUtils; -import com.alibaba.graphscope.groot.common.RoleType; -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.exception.GrootException; -import com.alibaba.graphscope.groot.discovery.*; -import com.alibaba.graphscope.groot.ingestor.IngestProgressFetcher; -import com.alibaba.graphscope.groot.ingestor.IngestService; -import com.alibaba.graphscope.groot.ingestor.IngestorSnapshotService; -import com.alibaba.graphscope.groot.ingestor.IngestorWriteService; -import com.alibaba.graphscope.groot.ingestor.RemoteIngestProgressFetcher; -import com.alibaba.graphscope.groot.ingestor.StoreWriteClient; -import com.alibaba.graphscope.groot.ingestor.StoreWriteClients; -import com.alibaba.graphscope.groot.ingestor.StoreWriter; -import com.alibaba.graphscope.groot.meta.DefaultMetaService; -import com.alibaba.graphscope.groot.meta.MetaService; -import com.alibaba.graphscope.groot.metrics.MetricsCollectService; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.rpc.ChannelManager; -import com.alibaba.graphscope.groot.rpc.GrootNameResolverFactory; -import com.alibaba.graphscope.groot.rpc.RpcServer; -import com.alibaba.graphscope.groot.wal.LogService; -import com.alibaba.graphscope.groot.wal.LogServiceFactory; - -import io.grpc.NameResolver; - -import org.apache.curator.framework.CuratorFramework; - -import java.io.IOException; - -public class Ingestor extends NodeBase { - - private CuratorFramework curator; - private NodeDiscovery discovery; - private ChannelManager channelManager; - private MetaService metaService; - - private IngestService ingestService; - private RpcServer rpcServer; - - public Ingestor(Configs configs) { - super(configs); - configs = reConfig(configs); - LocalNodeProvider localNodeProvider = new LocalNodeProvider(configs); - if (CommonConfig.DISCOVERY_MODE.get(configs).equalsIgnoreCase("file")) { - this.discovery = new FileDiscovery(configs); - } else { - this.curator = CuratorUtils.makeCurator(configs); - this.discovery = new ZkDiscovery(configs, localNodeProvider, this.curator); - } - NameResolver.Factory nameResolverFactory = new GrootNameResolverFactory(this.discovery); - this.channelManager = new ChannelManager(configs, nameResolverFactory); - this.metaService = new DefaultMetaService(configs); - LogService logService = LogServiceFactory.makeLogService(configs); - IngestProgressFetcher ingestProgressClients = - new RemoteIngestProgressFetcher(this.channelManager); - StoreWriter storeWriteClients = - new StoreWriteClients(this.channelManager, RoleType.STORE, StoreWriteClient::new); - MetricsCollector metricsCollector = new MetricsCollector(configs); - this.ingestService = - new IngestService( - configs, - this.discovery, - this.metaService, - logService, - ingestProgressClients, - storeWriteClients, - metricsCollector); - MetricsCollectService metricsCollectService = new MetricsCollectService(metricsCollector); - IngestorSnapshotService ingestorSnapshotService = - new IngestorSnapshotService(this.ingestService); - IngestorWriteService ingestorWriteService = new IngestorWriteService(this.ingestService); - this.rpcServer = - new RpcServer( - configs, - localNodeProvider, - ingestorSnapshotService, - ingestorWriteService, - metricsCollectService); - } - - @Override - public void start() { - if (this.curator != null) { - this.curator.start(); - } - this.metaService.start(); - try { - this.rpcServer.start(); - } catch (IOException e) { - throw new GrootException(e); - } - this.discovery.start(); - this.channelManager.start(); - this.ingestService.start(); - } - - @Override - public void close() throws IOException { - this.rpcServer.stop(); - this.ingestService.stop(); - this.metaService.stop(); - this.channelManager.stop(); - this.discovery.stop(); - if (this.curator != null) { - this.curator.close(); - } - } - - public static void main(String[] args) throws IOException { - String configFile = System.getProperty("config.file"); - Configs conf = new Configs(configFile); - Ingestor ingestor = new Ingestor(conf); - NodeLauncher nodeLauncher = new NodeLauncher(ingestor); - nodeLauncher.start(); - } -} diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/MaxNode.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/MaxNode.java index ea6416c34cfd..02d9fbd05f6f 100644 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/MaxNode.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/MaxNode.java @@ -33,7 +33,6 @@ public class MaxNode extends NodeBase { private KafkaTestCluster kafkaTestCluster; private final NodeBase coordinator; private final List frontends = new ArrayList<>(); - private final List ingestors = new ArrayList<>(); private final List stores = new ArrayList<>(); public MaxNode(Configs configs) throws Exception { @@ -49,7 +48,6 @@ public MaxNode(Configs configs) throws Exception { } int frontendCount = CommonConfig.FRONTEND_NODE_COUNT.get(configs); - int ingestorCount = CommonConfig.INGESTOR_NODE_COUNT.get(configs); int storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); Configs baseConfigs = @@ -72,14 +70,6 @@ public MaxNode(Configs configs) throws Exception { .build(); this.frontends.add(new Frontend(frontendConfigs)); } - for (int i = 0; i < ingestorCount; i++) { - Configs ingestConfigs = - Configs.newBuilder(baseConfigs) - .put(CommonConfig.ROLE_NAME.getKey(), RoleType.INGESTOR.getName()) - .put(CommonConfig.NODE_IDX.getKey(), String.valueOf(i)) - .build(); - this.ingestors.add(new Ingestor(ingestConfigs)); - } for (int i = 0; i < storeCount; i++) { Configs storeConfigs = Configs.newBuilder(baseConfigs) @@ -115,14 +105,6 @@ public void start() { logger.info("[" + frontend.getName() + "] started"); })); } - for (NodeBase ingestor : this.ingestors) { - startThreads.add( - new Thread( - () -> { - ingestor.start(); - logger.info("[" + ingestor.getName() + "] started"); - })); - } for (Thread startThread : startThreads) { startThread.start(); @@ -139,9 +121,6 @@ public void start() { @Override public void close() throws IOException { - for (NodeBase ingestor : this.ingestors) { - ingestor.close(); - } for (NodeBase frontend : this.frontends) { frontend.close(); } diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/NodeBase.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/NodeBase.java index 0527e9a02dd7..4d65e2c2dcb6 100755 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/NodeBase.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/NodeBase.java @@ -48,7 +48,6 @@ protected Configs reConfig(Configs configs) { System.setProperty( "io.grpc.netty.shaded.io.netty.eventLoopThreads", String.valueOf(nettyThreadCount)); int storeCount = CommonConfig.STORE_NODE_COUNT.get(configs); - int ingestorCount = CommonConfig.INGESTOR_NODE_COUNT.get(configs); return Configs.newBuilder(configs) .put( String.format(CommonConfig.NODE_COUNT_FORMAT, RoleType.GAIA_RPC.getName()), @@ -57,7 +56,6 @@ protected Configs reConfig(Configs configs) { String.format( CommonConfig.NODE_COUNT_FORMAT, RoleType.GAIA_ENGINE.getName()), String.valueOf(storeCount)) - .put(CommonConfig.INGESTOR_QUEUE_COUNT.getKey(), String.valueOf(ingestorCount)) .put(CommonConfig.ROLE_NAME.getKey(), this.roleType.getName()) .build(); } diff --git a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Store.java b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Store.java index 9d5acd3cd91b..0eda023a5832 100644 --- a/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Store.java +++ b/interactive_engine/groot-server/src/main/java/com/alibaba/graphscope/groot/servers/Store.java @@ -24,6 +24,8 @@ import com.alibaba.graphscope.groot.rpc.GrootNameResolverFactory; import com.alibaba.graphscope.groot.rpc.RpcServer; import com.alibaba.graphscope.groot.store.*; +import com.alibaba.graphscope.groot.wal.LogService; +import com.alibaba.graphscope.groot.wal.LogServiceFactory; import com.google.common.annotations.VisibleForTesting; import io.grpc.NameResolver; @@ -41,13 +43,14 @@ public class Store extends NodeBase { private RpcServer rpcServer; private AbstractService executorService; + private KafkaProcessor processor; + public Store(Configs configs) { super(configs); configs = reConfig(configs); LocalNodeProvider localNodeProvider = new LocalNodeProvider(configs); DiscoveryFactory discoveryFactory = new DiscoveryFactory(configs); this.discovery = discoveryFactory.makeDiscovery(localNodeProvider); - NameResolver.Factory nameResolverFactory = new GrootNameResolverFactory(this.discovery); this.channelManager = new ChannelManager(configs, nameResolverFactory); this.metaService = new DefaultMetaService(configs); @@ -55,6 +58,8 @@ public Store(Configs configs) { this.storeService = new StoreService(configs, this.metaService, metricsCollector); SnapshotCommitter snapshotCommitter = new DefaultSnapshotCommitter(this.channelManager); MetricsCollectService metricsCollectService = new MetricsCollectService(metricsCollector); + LogService logService = LogServiceFactory.makeLogService(configs); + this.writerAgent = new WriterAgent( configs, @@ -83,6 +88,8 @@ public Store(Configs configs) { ComputeServiceProducer serviceProducer = ServiceProducerFactory.getProducer(configs); this.executorService = serviceProducer.makeExecutorService(storeService, metaService, discoveryFactory); + + this.processor = new KafkaProcessor(configs, metaService, writerAgent, logService); } @Override @@ -110,10 +117,12 @@ public void start() { this.discovery.start(); this.channelManager.start(); this.executorService.start(); + this.processor.start(); } @Override public void close() throws IOException { + this.processor.stop(); this.executorService.stop(); this.rpcServer.stop(); this.backupAgent.stop(); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/DefaultMetaServiceTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/DefaultMetaServiceTest.java index fb6a9f255d52..87ea09de9d42 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/DefaultMetaServiceTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/DefaultMetaServiceTest.java @@ -31,7 +31,6 @@ void testMeta() { Configs configs = Configs.newBuilder() .put("partition.count", "10") - .put("ingestor.queue.count", "3") .put("store.node.count", "4") .build(); /** @@ -49,10 +48,7 @@ void testMeta() { () -> assertEquals(metaService.getStoreIdByPartition(6), 2), () -> assertEquals(metaService.getStoreIdByPartition(8), 3), () -> assertEquals(metaService.getPartitionsByStoreId(2), Arrays.asList(6, 7)), - () -> assertEquals(metaService.getQueueCount(), 3), - () -> assertEquals(metaService.getQueueIdsForIngestor(2), Arrays.asList(2)), - () -> assertEquals(metaService.getIngestorIdForQueue(1), 1)); - + () -> assertEquals(metaService.getQueueCount(), 4)); metaService.stop(); } } diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/wal/kafka/KafkaWalTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/wal/kafka/KafkaWalTest.java index 07489a40e190..2aabc28f03ef 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/wal/kafka/KafkaWalTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/common/wal/kafka/KafkaWalTest.java @@ -46,7 +46,7 @@ void testDoubleDestroy() { KafkaConfig.KAFKA_SERVERS.getKey(), sharedKafkaTestResource.getKafkaConnectString()) .put(KafkaConfig.KAKFA_TOPIC.getKey(), "test_double_destroy") - .put(CommonConfig.INGESTOR_QUEUE_COUNT.getKey(), "1") + .put(CommonConfig.STORE_NODE_COUNT.getKey(), "1") .build(); LogService logService = new KafkaLogService(configs); logService.init(); @@ -62,7 +62,7 @@ void testDoubleInit() { KafkaConfig.KAFKA_SERVERS.getKey(), sharedKafkaTestResource.getKafkaConnectString()) .put(KafkaConfig.KAKFA_TOPIC.getKey(), "test_double_init") - .put(CommonConfig.INGESTOR_QUEUE_COUNT.getKey(), "1") + .put(CommonConfig.STORE_NODE_COUNT.getKey(), "1") .build(); LogService logService = new KafkaLogService(configs); logService.init(); @@ -78,20 +78,20 @@ void testLogService() throws IOException { KafkaConfig.KAFKA_SERVERS.getKey(), sharedKafkaTestResource.getKafkaConnectString()) .put(KafkaConfig.KAKFA_TOPIC.getKey(), "test_logservice") - .put(CommonConfig.INGESTOR_QUEUE_COUNT.getKey(), "1") + .put(CommonConfig.STORE_NODE_COUNT.getKey(), "1") .build(); LogService logService = new KafkaLogService(configs); logService.init(); int queueId = 0; long snapshotId = 1L; - LogWriter writer = logService.createWriter(queueId); + LogWriter writer = logService.createWriter(); LogEntry logEntry = new LogEntry( snapshotId, OperationBatch.newBuilder() .addOperationBlob(OperationBlob.MARKER_OPERATION_BLOB) .build()); - assertEquals(writer.append(logEntry), 0); + assertEquals(writer.append(queueId, logEntry), 0); LogReader reader = logService.createReader(queueId, 0); ReadLogEntry readLogEntry = reader.readNext(); @@ -105,9 +105,9 @@ void testLogService() throws IOException { assertEquals(operationBatch.getOperationCount(), 1); assertEquals(operationBatch.getOperationBlob(0), OperationBlob.MARKER_OPERATION_BLOB); - assertEquals(writer.append(logEntry), 1); - assertEquals(writer.append(logEntry), 2); - assertEquals(writer.append(logEntry), 3); + assertEquals(writer.append(queueId, logEntry), 1); + assertEquals(writer.append(queueId, logEntry), 2); + assertEquals(writer.append(queueId, logEntry), 3); LogReader readerTail = logService.createReader(queueId, 4); assertNull(readerTail.readNext()); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/CoordinatorRpcTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/CoordinatorRpcTest.java index ec46156b28ad..8b7bb42eb223 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/CoordinatorRpcTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/CoordinatorRpcTest.java @@ -23,7 +23,6 @@ import com.alibaba.graphscope.groot.coordinator.BackupService; import com.alibaba.graphscope.groot.coordinator.SchemaService; import com.alibaba.graphscope.groot.coordinator.SnapshotCommitService; -import com.alibaba.graphscope.groot.frontend.IngestorWriteClient; import com.alibaba.graphscope.groot.rpc.RoleClients; import com.alibaba.graphscope.groot.schema.request.DdlException; import com.alibaba.graphscope.groot.store.StoreBackupId; @@ -37,18 +36,6 @@ import java.util.*; public class CoordinatorRpcTest { - - @Test - void testDdlWriter() { - RoleClients clients = mock(RoleClients.class); - IngestorWriteClient ingestorWriteClient = mock(IngestorWriteClient.class); - when(clients.getClient(0)).thenReturn(ingestorWriteClient); - - DdlWriter ddlWriter = new DdlWriter(clients); - ddlWriter.writeOperations("test_req", null); - verify(ingestorWriteClient).writeIngestor(eq("test_req"), eq(0), any()); - } - @Test void testGraphDefFetcher() { RoleClients clients = mock(RoleClients.class); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestProgressServiceTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestProgressServiceTest.java deleted file mode 100644 index bb22a53a90bc..000000000000 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestProgressServiceTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.tests.coordinator; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; - -import com.alibaba.graphscope.groot.coordinator.IngestProgressService; -import com.alibaba.graphscope.groot.coordinator.SnapshotManager; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsRequest; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsResponse; - -import io.grpc.stub.StreamObserver; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.List; - -public class IngestProgressServiceTest { - @Test - void testIngestProgressService() { - SnapshotManager snapshotManager = mock(SnapshotManager.class); - when(snapshotManager.getTailOffsets(Arrays.asList(1))).thenReturn(Arrays.asList(10L)); - IngestProgressService ingestProgressService = new IngestProgressService(snapshotManager); - GetTailOffsetsRequest request = GetTailOffsetsRequest.newBuilder().addQueueId(1).build(); - - ingestProgressService.getTailOffsets( - request, - new StreamObserver() { - @Override - public void onNext(GetTailOffsetsResponse response) { - List offsetsList = response.getOffsetsList(); - assertEquals(offsetsList.size(), 1); - assertEquals(offsetsList.get(0), 10L); - } - - @Override - public void onError(Throwable t) { - throw new RuntimeException(t); - } - - @Override - public void onCompleted() {} - }); - verify(snapshotManager).getTailOffsets(Arrays.asList(1)); - } -} diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestorWriteSnapshotIdNotifierTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestorWriteSnapshotIdNotifierTest.java index 8b41bd5de072..1e4f88a9c28d 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestorWriteSnapshotIdNotifierTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/IngestorWriteSnapshotIdNotifierTest.java @@ -28,7 +28,7 @@ public class IngestorWriteSnapshotIdNotifierTest { @Test void testNotifier() { Configs configs = - Configs.newBuilder().put(CommonConfig.INGESTOR_NODE_COUNT.getKey(), "1").build(); + Configs.newBuilder().put(CommonConfig.FRONTEND_NODE_COUNT.getKey(), "1").build(); RoleClients roleClients = mock(RoleClients.class); IngestorSnapshotClient ingestorSnapshotClient = mock(IngestorSnapshotClient.class); when(roleClients.getClient(0)).thenReturn(ingestorSnapshotClient); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/SnapshotManagerTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/SnapshotManagerTest.java index 05ccea69ae48..335841662a53 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/SnapshotManagerTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/coordinator/SnapshotManagerTest.java @@ -43,10 +43,8 @@ public class SnapshotManagerTest { void testSnapshotManager() throws IOException, InterruptedException { Configs configs = Configs.newBuilder() - .put(CommonConfig.INGESTOR_QUEUE_COUNT.getKey(), "1") .put(CommonConfig.STORE_NODE_COUNT.getKey(), "2") .put(CommonConfig.FRONTEND_NODE_COUNT.getKey(), "1") - .put(CommonConfig.INGESTOR_NODE_COUNT.getKey(), "1") .put(CoordinatorConfig.SNAPSHOT_INCREASE_INTERVAL_MS.getKey(), "1000") .put(CoordinatorConfig.OFFSETS_PERSIST_INTERVAL_MS.getKey(), "1000") .build(); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/frontend/FrontendRpcTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/frontend/FrontendRpcTest.java index db7fc3a65ce6..141647146587 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/frontend/FrontendRpcTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/frontend/FrontendRpcTest.java @@ -23,8 +23,6 @@ import com.alibaba.graphscope.groot.common.util.BackupInfo; import com.alibaba.graphscope.groot.frontend.*; import com.alibaba.graphscope.groot.frontend.FrontendSnapshotService; -import com.alibaba.graphscope.groot.operation.BatchId; -import com.alibaba.graphscope.groot.operation.OperationBatch; import com.alibaba.graphscope.groot.rpc.RoleClients; import com.alibaba.graphscope.groot.schema.request.DdlRequestBatch; import com.alibaba.graphscope.proto.groot.*; @@ -63,24 +61,6 @@ void testFrontendSnapshotService() { verify(streamObserver).onCompleted(); } - @Test - void testIngestorWriteClient() { - IngestorWriteGrpc.IngestorWriteBlockingStub stub = - mock(IngestorWriteGrpc.IngestorWriteBlockingStub.class); - IngestorWriteClient client = new IngestorWriteClient(stub); - when(stub.writeIngestor(any())) - .thenReturn(WriteIngestorResponse.newBuilder().setSnapshotId(10L).build()); - BatchId batchId = client.writeIngestor("test_req", 2, OperationBatch.newBuilder().build()); - assertEquals(batchId.getSnapshotId(), 10L); - verify(stub) - .writeIngestor( - WriteIngestorRequest.newBuilder() - .setRequestId("test_req") - .setQueueId(2) - .setOperationBatch(OperationBatch.newBuilder().build().toProto()) - .build()); - } - @Test void testSchemaClient() { SchemaGrpc.SchemaBlockingStub stub = mock(SchemaGrpc.SchemaBlockingStub.class); diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/BatchSenderTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/BatchSenderTest.java deleted file mode 100644 index b6bd3517af06..000000000000 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/BatchSenderTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.tests.ingestor; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.*; - -import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.schema.wrapper.LabelId; -import com.alibaba.graphscope.groot.ingestor.BatchSender; -import com.alibaba.graphscope.groot.ingestor.StoreWriter; -import com.alibaba.graphscope.groot.meta.MetaService; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.operation.OperationBlob; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; -import com.alibaba.graphscope.groot.operation.VertexId; -import com.alibaba.graphscope.groot.operation.dml.OverwriteVertexOperation; - -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class BatchSenderTest { - - @Test - void testSend() throws InterruptedException { - Configs configs = - Configs.newBuilder().put(CommonConfig.STORE_NODE_COUNT.getKey(), "1").build(); - MetaService mockMetaService = mock(MetaService.class); - when(mockMetaService.getPartitionCount()).thenReturn(2); - when(mockMetaService.getStoreIdByPartition(anyInt())).thenReturn(0); - - StoreWriter mockStoreWriter = mock(StoreWriter.class); - String requestId = "test_batch_sender"; - int queueId = 0; - long snapshotId = 10L; - long offset = 50L; - LabelId labelId = new LabelId(0); - OperationBlob writeVertexBlob1 = - new OverwriteVertexOperation(new VertexId(0L), labelId, Collections.EMPTY_MAP) - .toBlob(); - OperationBlob writeVertexBlob2 = - new OverwriteVertexOperation(new VertexId(1L), labelId, Collections.EMPTY_MAP) - .toBlob(); - OperationBatch batch = - OperationBatch.newBuilder() - .addOperationBlob(writeVertexBlob1) - .addOperationBlob(writeVertexBlob2) - .addOperationBlob(OperationBlob.MARKER_OPERATION_BLOB) - .build(); - - CountDownLatch latch = new CountDownLatch(1); - doAnswer( - invocationOnMock -> { - StoreDataBatch storeBatch = invocationOnMock.getArgument(1); - CompletionCallback callback = invocationOnMock.getArgument(2); - assertAll( - () -> assertEquals(storeBatch.getRequestId(), requestId), - () -> assertEquals(storeBatch.getQueueId(), queueId), - () -> assertEquals(storeBatch.getSnapshotId(), snapshotId), - () -> assertEquals(storeBatch.getOffset(), offset), - () -> assertEquals(storeBatch.getDataBatch().size(), 2)); - List> dataBatch = - storeBatch.getDataBatch(); - Map partitionToBatch = dataBatch.get(0); - assertAll( - () -> - assertEquals( - partitionToBatch.get(0).getOperationBlob(0), - writeVertexBlob1), - () -> - assertEquals( - partitionToBatch.get(1).getOperationBlob(0), - writeVertexBlob2)); - assertEquals( - dataBatch.get(1).get(-1).getOperationBlob(0), - OperationBlob.MARKER_OPERATION_BLOB); - callback.onCompleted(0); - latch.countDown(); - return null; - }) - .when(mockStoreWriter) - .write(anyInt(), any(), any()); - - BatchSender batchSender = - new BatchSender( - configs, mockMetaService, mockStoreWriter, new MetricsCollector(configs)); - batchSender.start(); - - batchSender.asyncSendWithRetry(requestId, queueId, snapshotId, offset, batch); - assertTrue(latch.await(5L, TimeUnit.SECONDS)); - - batchSender.stop(); - } -} diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestProcessorTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestProcessorTest.java deleted file mode 100644 index 413256bc6d97..000000000000 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestProcessorTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.tests.ingestor; - -import static org.mockito.Mockito.*; - -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.ingestor.BatchSender; -import com.alibaba.graphscope.groot.ingestor.IngestCallback; -import com.alibaba.graphscope.groot.ingestor.IngestProcessor; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.wal.LogReader; -import com.alibaba.graphscope.groot.wal.LogService; -import com.alibaba.graphscope.groot.wal.LogWriter; -import com.alibaba.graphscope.groot.wal.ReadLogEntry; - -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicLong; - -public class IngestProcessorTest { - - @Test - void testIngestProcessor() throws IOException { - long tailOffset = 50L; - int queueId = 0; - - Configs configs = Configs.newBuilder().build(); - LogService mockLogService = mock(LogService.class); - - LogReader mockLogReader = mock(LogReader.class); - when(mockLogService.createReader(queueId, tailOffset + 1)).thenReturn(mockLogReader); - - LogWriter mockLogWriter = mock(LogWriter.class); - when(mockLogService.createWriter(queueId)).thenReturn(mockLogWriter); - when(mockLogWriter.append(any())).thenReturn(tailOffset + 3); - - OperationBatch emptyBatch = OperationBatch.newBuilder().build(); - long readSnapshotId = 5L; - ReadLogEntry readLogEntry1 = new ReadLogEntry(tailOffset + 1, readSnapshotId, emptyBatch); - ReadLogEntry readLogEntry2 = new ReadLogEntry(tailOffset + 2, readSnapshotId, emptyBatch); - when(mockLogReader.readNext()) - .thenReturn(readLogEntry1) - .thenReturn(readLogEntry2) - .thenReturn(null); - - BatchSender mockBatchSender = mock(BatchSender.class); - AtomicLong ingestSnapshotId = new AtomicLong(10L); - - IngestProcessor ingestProcessor = - new IngestProcessor( - configs, - mockLogService, - mockBatchSender, - queueId, - ingestSnapshotId, - new MetricsCollector(configs)); - ingestProcessor.setTailOffset(tailOffset); - ingestProcessor.start(); - - verify(mockBatchSender, timeout(5000L)) - .asyncSendWithRetry( - eq(""), eq(queueId), eq(readSnapshotId), eq(tailOffset + 1), any()); - verify(mockBatchSender, timeout(5000L)) - .asyncSendWithRetry( - eq(""), eq(queueId), eq(readSnapshotId), eq(tailOffset + 2), any()); - verify(mockLogReader).close(); - - String requestId = "test_ingest_processor"; - IngestCallback mockIngestCallback = mock(IngestCallback.class); - ingestProcessor.ingestBatch(requestId, emptyBatch, mockIngestCallback); - - verify(mockBatchSender, timeout(5000L)) - .asyncSendWithRetry( - requestId, queueId, ingestSnapshotId.get(), tailOffset + 3, emptyBatch); - verify(mockIngestCallback, timeout(5000L)).onSuccess(ingestSnapshotId.get()); - - ingestProcessor.stop(); - verify(mockLogWriter, timeout(5000L)).close(); - } -} diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestServiceTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestServiceTest.java deleted file mode 100644 index 015827a0374d..000000000000 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestServiceTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2020 Alibaba Group Holding Limited. - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.graphscope.groot.tests.ingestor; - -import static org.mockito.Mockito.*; - -import com.alibaba.graphscope.groot.common.RoleType; -import com.alibaba.graphscope.groot.common.config.CommonConfig; -import com.alibaba.graphscope.groot.common.config.Configs; -import com.alibaba.graphscope.groot.common.config.IngestorConfig; -import com.alibaba.graphscope.groot.discovery.GrootNode; -import com.alibaba.graphscope.groot.discovery.NodeDiscovery; -import com.alibaba.graphscope.groot.ingestor.IngestProcessor; -import com.alibaba.graphscope.groot.ingestor.IngestProgressFetcher; -import com.alibaba.graphscope.groot.ingestor.IngestService; -import com.alibaba.graphscope.groot.ingestor.StoreWriter; -import com.alibaba.graphscope.groot.meta.MetaService; -import com.alibaba.graphscope.groot.metrics.MetricsCollector; -import com.alibaba.graphscope.groot.wal.LogService; - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -public class IngestServiceTest { - - @Test - void testIngestService() { - Configs configs = - Configs.newBuilder() - .put(CommonConfig.NODE_IDX.getKey(), "0") - .put(CommonConfig.STORE_NODE_COUNT.getKey(), "1") - .put(IngestorConfig.INGESTOR_CHECK_PROCESSOR_INTERVAL_MS.getKey(), "100") - .build(); - - MockDiscovery mockDiscovery = new MockDiscovery(); - - MetaService mockMetaService = mock(MetaService.class); - when(mockMetaService.getQueueIdsForIngestor(0)).thenReturn(Arrays.asList(0)); - - LogService mockLogService = mock(LogService.class); - - IngestProgressFetcher mockIngestProgressFetcher = mock(IngestProgressFetcher.class); - when(mockIngestProgressFetcher.getTailOffsets(Arrays.asList(0))) - .thenReturn(Arrays.asList(50L)); - - StoreWriter mockStoreWriter = mock(StoreWriter.class); - - IngestService spyIngestService = - spy( - new IngestService( - configs, - mockDiscovery, - mockMetaService, - mockLogService, - mockIngestProgressFetcher, - mockStoreWriter, - new MetricsCollector(configs))); - - IngestProcessor mockIngestProcessor = mock(IngestProcessor.class); - doReturn(mockIngestProcessor) - .when(spyIngestService) - .makeIngestProcessor(any(), any(), any(), eq(0), any(), any()); - spyIngestService.start(); - - verify(mockIngestProcessor, never()).start(); - mockDiscovery.addNode(RoleType.STORE, Collections.singletonMap(0, null)); - verify(mockIngestProcessor, timeout(5000L)).setTailOffset(50L); - verify(mockIngestProcessor, timeout(5000L)).start(); - - spyIngestService.advanceIngestSnapshotId(5L, null); - verify(mockIngestProcessor) - .ingestBatch(eq("marker"), eq(IngestService.MARKER_BATCH), any()); - - mockDiscovery.removeNode(RoleType.STORE, Collections.singletonMap(0, null)); - verify(mockIngestProcessor, timeout(5000L).times(2)).stop(); - - spyIngestService.stop(); - } - - class MockDiscovery implements NodeDiscovery { - - Listener listener = null; - - void addNode(RoleType roleType, Map nodes) { - listener.nodesJoin(roleType, nodes); - } - - void removeNode(RoleType roleType, Map nodes) { - listener.nodesLeft(roleType, nodes); - } - - @Override - public void start() {} - - @Override - public void stop() {} - - @Override - public void addListener(Listener listener) { - this.listener = listener; - } - - @Override - public void removeListener(Listener listener) { - this.listener = null; - } - - @Override - public GrootNode getLocalNode() { - return null; - } - } -} diff --git a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestorRpcTest.java b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestorRpcTest.java index 784ebdac634e..2848ca65bb99 100644 --- a/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestorRpcTest.java +++ b/interactive_engine/groot-server/src/test/java/com/alibaba/graphscope/groot/tests/ingestor/IngestorRpcTest.java @@ -13,43 +13,27 @@ */ package com.alibaba.graphscope.groot.tests.ingestor; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.*; import com.alibaba.graphscope.groot.CompletionCallback; -import com.alibaba.graphscope.groot.ingestor.IngestCallback; -import com.alibaba.graphscope.groot.ingestor.IngestProgressClient; -import com.alibaba.graphscope.groot.ingestor.IngestService; -import com.alibaba.graphscope.groot.ingestor.IngestorSnapshotService; -import com.alibaba.graphscope.groot.ingestor.IngestorWriteService; -import com.alibaba.graphscope.groot.ingestor.StoreWriteClient; -import com.alibaba.graphscope.groot.operation.OperationBatch; -import com.alibaba.graphscope.groot.operation.StoreDataBatch; +import com.alibaba.graphscope.groot.frontend.IngestorSnapshotService; +import com.alibaba.graphscope.groot.frontend.write.KafkaAppender; import com.alibaba.graphscope.proto.groot.AdvanceIngestSnapshotIdRequest; import com.alibaba.graphscope.proto.groot.AdvanceIngestSnapshotIdResponse; -import com.alibaba.graphscope.proto.groot.GetTailOffsetsResponse; -import com.alibaba.graphscope.proto.groot.IngestProgressGrpc; -import com.alibaba.graphscope.proto.groot.StoreWriteGrpc; -import com.alibaba.graphscope.proto.groot.WriteIngestorRequest; -import com.alibaba.graphscope.proto.groot.WriteIngestorResponse; -import com.alibaba.graphscope.proto.groot.WriteStoreResponse; import io.grpc.stub.StreamObserver; import org.junit.jupiter.api.Test; -import java.util.Arrays; -import java.util.List; - public class IngestorRpcTest { @Test void testIngestorSnapshotService() { - IngestService ingestService = mock(IngestService.class); + KafkaAppender kafkaAppender = mock(KafkaAppender.class); IngestorSnapshotService ingestorSnapshotService = - new IngestorSnapshotService(ingestService); + new IngestorSnapshotService(kafkaAppender); AdvanceIngestSnapshotIdRequest req = AdvanceIngestSnapshotIdRequest.newBuilder().setSnapshotId(10L).build(); StreamObserver streamObserver = mock(StreamObserver.class); @@ -59,7 +43,7 @@ void testIngestorSnapshotService() { callback.onCompleted(9L); return null; }) - .when(ingestService) + .when(kafkaAppender) .advanceIngestSnapshotId(anyLong(), any()); ingestorSnapshotService.advanceIngestSnapshotId(req, streamObserver); verify(streamObserver) @@ -69,61 +53,4 @@ void testIngestorSnapshotService() { .build()); verify(streamObserver).onCompleted(); } - - @Test - void testIngestorWriteService() { - IngestService ingestService = mock(IngestService.class); - IngestorWriteService ingestorWriteService = new IngestorWriteService(ingestService); - WriteIngestorRequest req = - WriteIngestorRequest.newBuilder() - .setQueueId(2) - .setRequestId("test_req") - .setOperationBatch(OperationBatch.newBuilder().build().toProto()) - .build(); - doAnswer( - invocation -> { - IngestCallback callback = invocation.getArgument(3); - callback.onSuccess(10L); - return null; - }) - .when(ingestService) - .ingestBatch(eq("test_req"), eq(2), eq(OperationBatch.newBuilder().build()), any()); - StreamObserver observer = mock(StreamObserver.class); - ingestorWriteService.writeIngestor(req, observer); - verify(observer).onNext(WriteIngestorResponse.newBuilder().setSnapshotId(10L).build()); - verify(observer).onCompleted(); - } - - @Test - void testIngestProgressClient() { - IngestProgressGrpc.IngestProgressBlockingStub stub = - mock(IngestProgressGrpc.IngestProgressBlockingStub.class); - IngestProgressClient client = new IngestProgressClient(stub); - when(stub.getTailOffsets(any())) - .thenReturn( - GetTailOffsetsResponse.newBuilder() - .addAllOffsets(Arrays.asList(10L, 20L, 30L)) - .build()); - List tailOffsets = client.getTailOffsets(Arrays.asList(1, 2, 3)); - assertEquals(tailOffsets, Arrays.asList(10L, 20L, 30L)); - } - - @Test - void testStoreWriteClient() { - StoreWriteGrpc.StoreWriteStub stub = mock(StoreWriteGrpc.StoreWriteStub.class); - StoreWriteClient client = new StoreWriteClient(stub); - CompletionCallback callback = mock(CompletionCallback.class); - doAnswer( - invocation -> { - StreamObserver observer = invocation.getArgument(1); - observer.onNext( - WriteStoreResponse.newBuilder().setSuccess(true).build()); - return null; - }) - .when(stub) - .writeStore(any(), any()); - client.writeStore( - Arrays.asList(StoreDataBatch.newBuilder().requestId("test_req").build()), callback); - verify(callback).onCompleted(12); - } } diff --git a/interactive_engine/groot-server/src/test/resources/gremlin-test.config b/interactive_engine/groot-server/src/test/resources/gremlin-test.config index 8a3f055be2b4..84a1a4cd3f8f 100644 --- a/interactive_engine/groot-server/src/test/resources/gremlin-test.config +++ b/interactive_engine/groot-server/src/test/resources/gremlin-test.config @@ -4,9 +4,7 @@ node.idx= rpc.port=0 store.node.count=1 frontend.node.count=1 -ingestor.node.count=2 coordinator.node.count=1 -ingestor.queue.count=2 partition.count=4 discovery.mode=zookeeper diff --git a/k8s/dockerfiles/graphscope-store.Dockerfile b/k8s/dockerfiles/graphscope-store.Dockerfile index 4ac9d509e23e..738125779428 100644 --- a/k8s/dockerfiles/graphscope-store.Dockerfile +++ b/k8s/dockerfiles/graphscope-store.Dockerfile @@ -25,7 +25,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -y && \ apt-get install -y sudo default-jdk dnsutils tzdata \ - libjemalloc-dev libunwind-dev binutils && \ + libjemalloc-dev libunwind-dev binutils less && \ apt-get clean -y && \ rm -rf /var/lib/apt/lists/* diff --git a/proto/groot/ingestor_snapshot_service.proto b/proto/groot/ingestor_snapshot_service.proto index cb5cf4f39d7b..ba6fd2a2faca 100644 --- a/proto/groot/ingestor_snapshot_service.proto +++ b/proto/groot/ingestor_snapshot_service.proto @@ -34,30 +34,8 @@ message AdvanceIngestSnapshotIdResponse { } -service IngestProgress { - rpc getTailOffsets(GetTailOffsetsRequest) returns(GetTailOffsetsResponse); -} - -message GetTailOffsetsRequest { - repeated int32 queueId = 1; -} - -message GetTailOffsetsResponse { - repeated int64 offsets = 1; -} - service IngestorWrite { rpc writeIngestor(WriteIngestorRequest) returns (WriteIngestorResponse); - rpc replayWAL(ReplayWALRequest) returns (ReplayWALResponse); -} - -message ReplayWALRequest { - int64 offset = 1; - int64 timestamp = 2; -} - -message ReplayWALResponse { - repeated int64 snapshotId = 1; }