"not only SQL", "non-SQL"으로도 불리는 NoSQL은 관계형 데이터베이스의 전통적인 구조 밖에서 데이터 저장 및 쿼리를 가능하게 하는 데이터베이스 설계 접근법입니다. NoSQL은 여전히 관계형 데이터베이스 관리 시스템(Relational Database Management System, RDBMS)에서 찾을 수 있는 데이터를 저장할 수 있지만 RDBMS와는 다른 방식으로 데이터를 저장합니다. 관계형 데이터베이스와 비관계형 데이터베이스 중 무엇을 사용할지에 대한 결정은 크게 컨텍스트의 영향을 받으며, 적용사례에 따라 달라집니다.
관계형 데이터베이스의 전형적인 테이블 구조 대신, NoSQL 데이터베이스는 JSON 문서와 같은 하나의 데이터 구조 안에 데이터를 보관합니다. 이러한 비관계형 데이터베이스 설계는 스키마가 필요하지 않으므로 일반적으로 비정형인 대규모 데이터 세트를 관리할 수 있는 신속한 확장성을 제공합니다.
NoSQL은 또한 분산 데이터베이스의 한 유형입니다. 즉, 정보가 다양한 서버에 복제 및 저장되며, 서버는 원격이거나 로컬일 수 있습니다. 그러므로 데이터의 가용성과 신뢰성이 유지됩니다. 데이터 중 일부가 오프라인 상태가 되어도 데이터베이스의 나머지 부분은 계속 실행될 수 있습니다.
요즘, 거의 모든 산업에서 기업들은 고속으로 대량의 데이터를 관리해야 하며, 최신 웹 애플리케이션을 실행하기 위해 신속하게 확장할 수 있어야 합니다. 클라우드, 빅데이터, 모바일 및 웹 애플리케이션 내에서 확장이 중시되는 이 시대에 NoSQL 데이터베이스는 필요한 속도와 확장성을 제공하며, 성능과 사용 편의성 때문에 널리 선택되고 있습니다.
mongoDB는 JSON 기반의 문서 저장소 유형
JSON document = {"id":"01", "languange":"java"}
MongoDB와 RDBMS (Relational Database Management System)는 데이터를 저장하고 관리하는 데 사용되는 서로 다른 두 가지 데이터베이스입니다. 두 가지 주요 차이점은 다음과 같습니다.
데이터 모델 : MongoDB와 RDBMS 의 주요 차이점은 데이터를 저장하고 구성하는 방법입니다. MongoDB는 선택적 스키마와 함께 JSON과 유사한 문서에 데이터를 저장하는 문서 지향 데이터 모델을 사용합니다. 반면에 RDBMS 는 데이터가 고정된 스키마가 있는 테이블에 저장되는 테이블 형식 데이터 모델을 사용합니다.
확장 성 : MongoDB는 비용이 많이 드는 하드웨어 업데이트 없이 확장되는 데이터 및 읽기/쓰기 워크로드를 처리할 수 있는 방식으로 구성되어 있어 수요 증가에 따라 효율적으로 확장할 수 있습니다. RDBMS 도 확장할 수 있지만 일반적으로 더 복잡한 구성이 필요하고 추가 하드웨어를 사용해야 할 수도 있습니다.
인덱싱 : MongoDB와 RDBMS 모두 인덱싱을 지원하여 쿼리 및 검색 성능을 향상시킵니다. 그러나 지원되는 인덱스의 유형과 구현 방식은 둘 사이에서 다를 수 있습니다.
트랜잭션 : RDBMS 는 일반적으로 여러 작업을 단일 작업 단위로 처리하고 전체적으로 커밋하거나 롤백할 수 있는 트랜잭션을 지원합니다. MongoDB는 동일한 방식으로 트랜잭션을 지원하지 않지만 원자성 작업을 구현하기 위한 몇 가지 대안을 제공합니다.
언어 지원 : MongoDB와 RDBMS 모두 광범위한 프로그래밍 언어와 함께 사용할 수 있습니다. 그러나 지원되는 특정 언어와 사용 방식은 두 언어 간에 다를 수 있습니다.
MongoDB와 RDBMS 는 데이터를 저장하고 관리하기 위한 강력한 도구이지만 서로 다른 강점을 가지고 있으며 서로 다른 애플리케이션에 가장 적합합니다.
Replica Set에서는 마스터 - 슬레이브 대신,
주 노드(primary) - 보조(secondary) 노드 용어를 사용한다.
기본적인 Replica Set의 형태
MongoDB의 주 노드는 클라이언트 앱들의 쓰기/읽기 요청을 모두 받는다. 이 작업을 수행하고, 변화된 모든 내용을 운영 로그(oplog)에 남긴다. 보조 노드들은 oplog에 기록된 내용들을 동일하게 연산하여 주 노드와 항상 같은 데이터를 유지한다. 즉 운영 로그 전달을 통해 보조 노드가 동일한 연산을 수행하여 데이터의 정합성을 맞추는 방식이다.
주 노드의 교체
주 노드와 보조 노드 사이에 주기적으로 주고받는 heartbeat 신호를 통해 주 노드가 정상적이지 않은 상황이라는 것을 발견하면, 나머지 보조 노드들의 투표(election)을 통해 새로운 주 노드를 선발한다. 원래의 주 노드가 정상 상태로 돌아오게 되면, 다시금 주 노드의 역할을 맡게 된다.
Case 1) 주 노드 서버가 정상인 경우
Case 2) 주 노드 서버가 정상 작동하지 않는 경우
보조 노드들은 자신들의 health 상태와 미리 지정된 Priority 값을 판단하여 어떤 보조 노드가 주 노드로 승격될 것인지에 대한 투표를 한다. 만약 동일한 점수가 나오면 가장 최근에 반영된 데이터를 반영한 보조 노드가 승격 대상이다.
투표가 끝나기 전까지 Read 수행은 보조 노드를 통해 가능하도록 미리 설정할 수 있지만, 주 노드가 없는 상태이므로 Write 수행은 불가능하다. 기본 설정이라면 투표 시간은 12초를 넘기지 않는다. MongoDB 3.6 이상 버전의 드라이버들은 주노드가 정상 상황이 아닌 경우 실패한 Write 연산을 retry 하는 기능이 있다.
결정권자(Arbiter)
결정권자는 주 노드의 데이터를 복제하지 않는다. 데이터가 없기 때문에 주 노드가 될 수 없다. 결정권자의 역할은 heartbeat을 통해 각 노드의 상태를 확인하고, 유사시 투표에만 참가한다.
샤딩 이란?
샤딩은 여러 장비에 걸쳐 데이터를 분할하는 과정을 뜻한다. 각 장비에 데이터의 서브셋을 넣음으로써, 더 많은 수의 덜 강력한 장비로 더 많은 데이터를 저장하고 더 많은 부하를 처리할 수 있다. 컬렉션을 분할한 조각 데이터(청그)를 저장하며, 복제 세트로 구성될 수 있다.
몽고DB 에서의 자동 샤딩
몽고DB는 애플리케이션에서 구조를 추상화하고 시스템 관리를 간단하게 하는 자동 샤딩을 지원한다. 몽고DB가 샤드에 걸쳐 데이터 분산을 자동화하므로 용량을 추가하고 제거하기 쉽다.
클러스터 구성 요소
몽고DB 샤딩을 통해, 많은 장비(샤드)의 클러스터를 생성하고, 각 샤드에 데이터 서브셋을 넣음으로써 데이터를 쪼갤 수 있다. 샤딩의 목적은 2개, 3개, 10개, 심지어 1000개의 샤드 클러스터가 하나의 장비처럼 보이게 하는 것이다. 이러한 세부 사항을 애플케이션으로부터 숨기기 위해, 샤드 앞단에 있는 mongos라는 라우팅 프로세스를 실행한다.
mongos
어떤 샤드가 어떤 데이터를 포함하는지 알려주는 '컨텐츠 목차'가 있다. 애플리케이션은 라우터에 연결해 정상적으로 요청을 발행할 수 있다. 라우터는 어떤 데이터가 어떤 샤드에 있는지 알기 때문에 요청을 적절한 샤드로 전달할 수 있다. 요청에 대한 응답이 있으면 라우터는 응답을 수집하고 필요하다면 통합하여 애플리케이션으로 되돌려보낸다.
Mongos - 다수 구성된 샤드의 인터페이스 역할, 클라이언트 요청의 올바른 샤드로 라우팅
Config Servers - 전체 클러스터의 메타 데이터, 구성 설정을 저장하는 서버
root@rook-01:~/mongodb# kubectl apply --server-side -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/crd.yaml
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbbackups.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbrestores.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbs.psmdb.percona.com serverside-applied
root@rook-01:~/mongodb# kubectl get crd | grep psmdb
perconaservermongodbbackups.psmdb.percona.com 2023-11-10T01:21:49Z
perconaservermongodbrestores.psmdb.percona.com 2023-11-10T01:21:49Z
perconaservermongodbs.psmdb.percona.com 2023-11-10T01:21:59Z
root@rook-01:~/mongodb# kubectl create ns psmdb
namespace/psmdb created
## kubectl-ns 설치 필요
# curl -O https://raw.githubusercontent.com/weibeld/kubectl-ns/master/kubectl-ns
# chmod +x kubectl-ns
# install kubectl-ns /usr/local/bin/
# git clone https://github.com/junegunn/fzf.git ~/.fzf
# ~/.fzf/install
# source ~/.bashrc
# kubectl-ns // namespace psmdb로 변경
root@rook-01:~/mongodb# kubectl apply -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/rbac.yaml
role.rbac.authorization.k8s.io/percona-server-mongodb-operator created
serviceaccount/percona-server-mongodb-operator created
rolebinding.rbac.authorization.k8s.io/service-account-percona-server-mongodb-operator created
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/operator.yaml
root@rook-01:~/mongodb# k apply -f operator.yaml
deployment.apps/percona-server-mongodb-operator created
root@rook-01:~/mongodb# kubectl get deploy,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/percona-server-mongodb-operator 1/1 1 1 29s
NAME READY STATUS RESTARTS AGE
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd 1/1 Running 0 29s
## 각자 닉네임 변수 지정
root@rook-01:~/mongodb# MYNICK=yoojh5099
root@rook-01:~/mongodb# echo "export MYNICK=yoojh5099" >> /etc/profile
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/secrets.yaml
root@rook-01:~/mongodb# cat secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-cluster-name-secrets
type: Opaque
stringData:
MONGODB_BACKUP_USER: backup
MONGODB_BACKUP_PASSWORD: backup123456
MONGODB_DATABASE_ADMIN_USER: databaseAdmin
MONGODB_DATABASE_ADMIN_PASSWORD: databaseAdmin123456
MONGODB_CLUSTER_ADMIN_USER: clusterAdmin
MONGODB_CLUSTER_ADMIN_PASSWORD: clusterAdmin123456
MONGODB_CLUSTER_MONITOR_USER: clusterMonitor
MONGODB_CLUSTER_MONITOR_PASSWORD: clusterMonitor123456
MONGODB_USER_ADMIN_USER: userAdmin
MONGODB_USER_ADMIN_PASSWORD: userAdmin123456
PMM_SERVER_API_KEY: apikey
PMM_SERVER_USER: admin
PMM_SERVER_PASSWORD: admin
root@rook-01:~/mongodb# cat secrets.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f -
secret/yoojh5099-secrets created
root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets
root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets -o json | jq .data
{
"MONGODB_BACKUP_PASSWORD": "YmFja3VwMTIzNDU2",
"MONGODB_BACKUP_USER": "YmFja3Vw",
"MONGODB_CLUSTER_ADMIN_PASSWORD": "Y2x1c3RlckFkbWluMTIzNDU2",
"MONGODB_CLUSTER_ADMIN_USER": "Y2x1c3RlckFkbWlu",
"MONGODB_CLUSTER_MONITOR_PASSWORD": "Y2x1c3Rlck1vbml0b3IxMjM0NTY=",
"MONGODB_CLUSTER_MONITOR_USER": "Y2x1c3Rlck1vbml0b3I=",
"MONGODB_DATABASE_ADMIN_PASSWORD": "ZGF0YWJhc2VBZG1pbjEyMzQ1Ng==",
"MONGODB_DATABASE_ADMIN_USER": "ZGF0YWJhc2VBZG1pbg==",
"MONGODB_USER_ADMIN_PASSWORD": "dXNlckFkbWluMTIzNDU2",
"MONGODB_USER_ADMIN_USER": "dXNlckFkbWlu",
"PMM_SERVER_API_KEY": "YXBpa2V5",
"PMM_SERVER_PASSWORD": "YWRtaW4=",
"PMM_SERVER_USER": "YWRtaW4="
}
# 클러스터 생성 : 복제 세트(3개 파드) replsets(rs0, size 3)
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cr.yaml
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cluster1.yaml
cat cluster1.yaml | yh
cat cluster1.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f - && kubectl get psmdb -w
# 클러스터 생성 정보 확인 : 약자 psmdb
kubectl get perconaservermongodbs
root@rook-01:~/mongodb# kubectl get psmdb
NAME ENDPOINT STATUS AGE
yoojh5099 yoojh5099-rs0.psmdb.svc.cluster.local ready 3m38s
# 클러스타 파드 정보 확인
root@rook-01:~/mongodb# kubectl get sts,pod -owide
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/yoojh5099-rs0 3/3 4m1s mongod percona/percona-server-mongodb:6.0.9-7
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd 1/1 Running 0 9m38s 10.244.140.226 rook-02 <none> <none>
pod/yoojh5099-rs0-0 1/1 Running 0 4m 10.244.140.224 rook-02 <none> <none>
pod/yoojh5099-rs0-1 1/1 Running 0 2m56s 10.244.125.228 rook-03 <none> <none>
pod/yoojh5099-rs0-2 1/1 Running 0 2m9s 10.244.155.116 rook-01 <none> <none>
root@rook-01:~/mongodb# kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/yoojh5099-rs0 ClusterIP None <none> 27017/TCP 4m3s
NAME ENDPOINTS AGE
endpoints/yoojh5099-rs0 10.244.125.228:27017,10.244.140.224:27017,10.244.155.116:27017 4m3s
root@rook-01:~/mongodb# kubectl df-pv
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-42d55079-12ba-454d-be48-c01f76164808 mongod-data-yoojh5099-rs0-2 psmdb rook-01 yoojh5099-rs0-2 mongod-data 99Gi 1696Mi 98Gi 1.66 226 52428062 0.00
pvc-3ceacd1e-6105-4566-9959-f8e374842255 mongod-data-yoojh5099-rs0-1 psmdb rook-03 yoojh5099-rs0-1 mongod-data 99Gi 1694Mi 98Gi 1.66 192 52428096 0.00
pvc-37fcb569-761a-44e3-89a8-13df53a6e599 mongod-data-yoojh5099-rs0-0 psmdb rook-02 yoojh5099-rs0-0 mongod-data 99Gi 1377Mi 98Gi 1.35 112 52428176 0.00
root@rook-01:~/mongodb# kubectl get pvc,pv
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mongod-data-yoojh5099-rs0-0 Bound pvc-37fcb569-761a-44e3-89a8-13df53a6e599 3Gi RWO nfs-storageclass 4m9s
persistentvolumeclaim/mongod-data-yoojh5099-rs0-1 Bound pvc-3ceacd1e-6105-4566-9959-f8e374842255 3Gi RWO nfs-storageclass 3m5s
persistentvolumeclaim/mongod-data-yoojh5099-rs0-2 Bound pvc-42d55079-12ba-454d-be48-c01f76164808 3Gi RWO nfs-storageclass 2m18s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-1932857f-49bf-41e0-b94c-c7187fb68a66 2Gi RWO Delete Terminating mysql-cluster/datadir-mycluster-2 local-path 18d
persistentvolume/pvc-2fd5b199-4b2f-4ff2-9941-eacd1623f182 2Gi RWO Delete Bound mysql-cluster/datadir-mycluster-0 local-path 18d
persistentvolume/pvc-37fcb569-761a-44e3-89a8-13df53a6e599 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-0 nfs-storageclass 4m9s
persistentvolume/pvc-3ceacd1e-6105-4566-9959-f8e374842255 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-1 nfs-storageclass 3m5s
persistentvolume/pvc-42d55079-12ba-454d-be48-c01f76164808 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-2 nfs-storageclass 2m18s
persistentvolume/pvc-c746bca6-2fd1-4d0d-a7a7-00633d5d50f1 2Gi RWO Delete Bound mysql-cluster/datadir-mycluster-1 local-path 18d
# mongodb 이미지 버전 확인
root@rook-01:~/mongodb# kubectl get perconaservermongodbs $MYNICK -o jsonpath={.spec.image} ; echo
percona/percona-server-mongodb:6.0.9-7
# 헤드리스 서비스 확인 : ClusterIP None
root@rook-01:~/mongodb# kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/yoojh5099-rs0 ClusterIP None <none> 27017/TCP 6m35s
NAME ENDPOINTS AGE
endpoints/yoojh5099-rs0 10.244.125.228:27017,10.244.140.224:27017,10.244.155.116:27017 6m35s
# 엔드포인트 슬라이스 정보 확인
root@rook-01:~/mongodb# kubectl describe endpointslices
Name: yoojh5099-rs0-nfwzv
Namespace: psmdb
Labels: app.kubernetes.io/instance=yoojh5099
app.kubernetes.io/managed-by=percona-server-mongodb-operator
app.kubernetes.io/name=percona-server-mongodb
app.kubernetes.io/part-of=percona-server-mongodb
app.kubernetes.io/replset=rs0
endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.io
kubernetes.io/service-name=yoojh5099-rs0
service.kubernetes.io/headless=
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2023-11-10T02:14:59Z
AddressType: IPv4
Ports:
Name Port Protocol
---- ---- --------
mongodb 27017 TCP
Endpoints:
- Addresses: 10.244.140.224
Conditions:
Ready: true
Hostname: yoojh5099-rs0-0
TargetRef: Pod/yoojh5099-rs0-0
NodeName: rook-02
Zone: <unset>
- Addresses: 10.244.125.228
Conditions:
Ready: true
Hostname: yoojh5099-rs0-1
TargetRef: Pod/yoojh5099-rs0-1
NodeName: rook-03
Zone: <unset>
- Addresses: 10.244.155.116
Conditions:
Ready: true
Hostname: yoojh5099-rs0-2
TargetRef: Pod/yoojh5099-rs0-2
NodeName: rook-01
Zone: <unset>
Events: <none>
# netshoot 이미지로 netdebug 파드에 zsh 실행
root@rook-01:~/mongodb# kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh
netdebug ~ MYNICK=yoojh5099
netdebug ~ nslookup $MYNICK-rs0
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.155.116
Name: yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.125.228
Name: yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.140.224
netdebug ~ nslookup -type=srv $MYNICK-rs0
Server: 10.96.0.10
Address: 10.96.0.10#53
yoojh5099-rs0.psmdb.svc.cluster.local service = 0 33 27017 yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local.
yoojh5099-rs0.psmdb.svc.cluster.local service = 0 33 27017 yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local.
yoojh5099-rs0.psmdb.svc.cluster.local service = 0 33 27017 yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local.
## MongoDB CLINET 사전 준비
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/myclient.yaml
root@rook-01:~/mongodb# VERSION=4.4.24-23 envsubst < myclient.yaml | kubectl apply -f -
daemonset.apps/myclient created
root@rook-01:~/mongodb# kubectl get pod -l name=mongodb -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myclient-8988r 1/1 Running 0 39s 10.244.155.117 rook-01 <none> <none>
myclient-w84ms 1/1 Running 0 39s 10.244.125.231 rook-03 <none> <none>
myclient-wcrcb 1/1 Running 0 39s 10.244.140.229 rook-02 <none> <none>
# [터미널2] 클러스터 접속(CLUSTER_USER)
root@rook-01:~# kubectl exec ds/myclient -it -- mongo --quiet "mongodb+srv://clusterAdmin:clusterAdmin123456@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"
# 복제 셋 정보 확인 : 구성원 상태 확인
rs0:PRIMARY> rs.status()['members']
[
{
"_id" : 0,
"name" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 12114,
"optime" : {
"ts" : Timestamp(1699594509, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-11-10T05:35:09Z"),
"lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1699582473, 2),
"electionDate" : ISODate("2023-11-10T02:14:33Z"),
"configVersion" : 8,
"configTerm" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 12024,
"optime" : {
"ts" : Timestamp(1699594509, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1699594509, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-11-10T05:35:09Z"),
"optimeDurableDate" : ISODate("2023-11-10T05:35:09Z"),
"lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"lastHeartbeat" : ISODate("2023-11-10T05:35:10.499Z"),
"lastHeartbeatRecv" : ISODate("2023-11-10T05:35:12.073Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 8,
"configTerm" : 1
},
{
"_id" : 2,
"name" : "yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11993,
"optime" : {
"ts" : Timestamp(1699594509, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1699594509, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-11-10T05:35:09Z"),
"optimeDurableDate" : ISODate("2023-11-10T05:35:09Z"),
"lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
"lastHeartbeat" : ISODate("2023-11-10T05:35:10.479Z"),
"lastHeartbeatRecv" : ISODate("2023-11-10T05:35:11.275Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 8,
"configTerm" : 1
}
]
# 복제 셋 정보 확인* : 간략히 확인, 자주 확인하는 명령어
rs0:PRIMARY> db.isMaster()
{
"topologyVersion" : {
"processId" : ObjectId("654d91be65f6a103594dd132"),
"counter" : NumberLong(13)
},
"hosts" : [
"yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017"
],
"setName" : "rs0",
"setVersion" : 8,
"ismaster" : true,
"secondary" : false,
"primary" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"tags" : {
"podName" : "yoojh5099-rs0-0",
"serviceName" : "yoojh5099"
},
"me" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1699594525, 1),
"t" : NumberLong(1)
},
"lastWriteDate" : ISODate("2023-11-10T05:35:25Z"),
"majorityOpTime" : {
"ts" : Timestamp(1699594525, 1),
"t" : NumberLong(1)
},
"majorityWriteDate" : ISODate("2023-11-10T05:35:25Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2023-11-10T05:35:28.898Z"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 22390,
"minWireVersion" : 0,
"maxWireVersion" : 17,
"readOnly" : false,
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1699594525, 1),
"signature" : {
"hash" : BinData(0,"LhHJ2BN60o79+ST9QB2jMmKDkaY="),
"keyId" : NumberLong("7299651142684770308")
}
},
"operationTime" : Timestamp(1699594525, 1)
}
# 오피로그 정보 확인 : 크기, 연산 시간
rs0:PRIMARY> rs.printReplicationInfo()
configured oplog size: 5048.650146484375MB
log length start to end: 12067secs (3.35hrs)
oplog first event time: Fri Nov 10 2023 02:14:33 GMT+0000 (UTC)
oplog last event time: Fri Nov 10 2023 05:35:40 GMT+0000 (UTC)
now: Fri Nov 10 2023 05:35:46 GMT+0000 (UTC)
# 동기화 상태 확인 : 세컨더리 구성원이 프라이머리의 어디까지 정보를 동기화했는지 확인
rs0:PRIMARY> rs.printSecondaryReplicationInfo()
source: yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017
syncedTo: Fri Nov 10 2023 05:35:56 GMT+0000 (UTC)
0 secs (0 hrs) behind the primary
source: yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017
syncedTo: Fri Nov 10 2023 05:35:56 GMT+0000 (UTC)
0 secs (0 hrs) behind the primary
# 복제 옵션 정보 확인
rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 8,
"term" : 1,
"members" : [
{
"_id" : 0,
"host" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
"podName" : "yoojh5099-rs0-0",
"serviceName" : "yoojh5099"
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
"podName" : "yoojh5099-rs0-1",
"serviceName" : "yoojh5099"
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
"podName" : "yoojh5099-rs0-2",
"serviceName" : "yoojh5099"
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
}
],
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("654d920965f6a103594dd169")
}
}
# 클러스터 생성 : 복제 셋 2개(rs-0, rs1), mongos(파드 3개), cfg(파드 3개) >> 6분 정도 소요
root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets
NAME TYPE DATA AGE
yoojh5099-secrets Opaque 13 3h36m
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cluster2.yaml
root@rook-01:~/mongodb# cat cluster2.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f -
perconaservermongodb.psmdb.percona.com/yoojh5099 configured
root@rook-01:~/mongodb# kubectl get psmdb,sts,pod,svc,ep,pvc,pv
NAME ENDPOINT STATUS AGE
perconaservermongodb.psmdb.percona.com/yoojh5099 yoojh5099-mongos.psmdb.svc.cluster.local ready 94m
NAME READY AGE
statefulset.apps/yoojh5099-cfg 3/3 94m
statefulset.apps/yoojh5099-mongos 3/3 92m
statefulset.apps/yoojh5099-rs0 3/3 94m
statefulset.apps/yoojh5099-rs1 3/3 94m
NAME READY STATUS RESTARTS AGE
pod/myclient-8988r 1/1 Running 0 4h19m
pod/myclient-w84ms 1/1 Running 0 4h19m
pod/myclient-wcrcb 1/1 Running 0 4h19m
pod/netdebug 0/1 Completed 0 5h7m
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd 1/1 Running 0 5h20m
pod/yoojh5099-cfg-0 1/1 Running 0 94m
pod/yoojh5099-cfg-1 1/1 Running 0 93m
pod/yoojh5099-cfg-2 1/1 Running 0 93m
pod/yoojh5099-mongos-0 1/1 Running 0 92m
pod/yoojh5099-mongos-1 1/1 Running 0 91m
pod/yoojh5099-mongos-2 1/1 Running 0 91m
pod/yoojh5099-rs0-0 1/1 Running 0 94m
pod/yoojh5099-rs0-1 1/1 Running 0 93m
pod/yoojh5099-rs0-2 1/1 Running 0 93m
pod/yoojh5099-rs1-0 1/1 Running 0 94m
pod/yoojh5099-rs1-1 1/1 Running 0 93m
pod/yoojh5099-rs1-2 1/1 Running 0 92m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/yoojh5099-cfg ClusterIP None <none> 27017/TCP 94m
service/yoojh5099-mongos ClusterIP 10.103.197.163 <none> 27017/TCP 92m
service/yoojh5099-rs0 ClusterIP None <none> 27017/TCP 94m
service/yoojh5099-rs1 ClusterIP None <none> 27017/TCP 94m
NAME ENDPOINTS AGE
endpoints/yoojh5099-cfg 10.244.125.239:27017,10.244.140.246:27017,10.244.155.122:27017 94m
endpoints/yoojh5099-mongos 10.244.125.241:27017,10.244.140.223:27017,10.244.155.124:27017 92m
endpoints/yoojh5099-rs0 10.244.125.238:27017,10.244.140.238:27017,10.244.155.121:27017 94m
endpoints/yoojh5099-rs1 10.244.125.240:27017,10.244.140.241:27017,10.244.155.123:27017 94m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mongod-data-yoojh5099-cfg-0 Bound pvc-b8f3bc27-af6f-4418-b256-be896a7b09ce 3Gi RWO nfs-storageclass 94m
persistentvolumeclaim/mongod-data-yoojh5099-cfg-1 Bound pvc-77f02240-47ae-48ba-9fb7-35e6d35dab7a 3Gi RWO nfs-storageclass 93m
persistentvolumeclaim/mongod-data-yoojh5099-cfg-2 Bound pvc-a6b9a807-a854-4ca6-93f9-4f679e421955 3Gi RWO nfs-storageclass 93m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-0 Bound pvc-ec5211d2-8390-48ed-aa1f-a802aedd1a39 3Gi RWO nfs-storageclass 94m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-1 Bound pvc-8cce3b0b-a823-4dff-b9cf-480f4480e4f0 3Gi RWO nfs-storageclass 93m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-2 Bound pvc-30ded14b-d55b-490f-87ed-f51f1c6fd1f8 3Gi RWO nfs-storageclass 93m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-0 Bound pvc-dce20a6f-ec48-4a9d-b907-4a32e171db87 3Gi RWO nfs-storageclass 94m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-1 Bound pvc-33402b1c-8c54-47e0-ae33-2aef70ed0463 3Gi RWO nfs-storageclass 93m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-2 Bound pvc-d008eb7f-2e0b-4f3d-a49f-b73d4d524e49 3Gi RWO nfs-storageclass 92m
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-1932857f-49bf-41e0-b94c-c7187fb68a66 2Gi RWO Delete Terminating mysql-cluster/datadir-mycluster-2 local-path 18d
persistentvolume/pvc-2fd5b199-4b2f-4ff2-9941-eacd1623f182 2Gi RWO Delete Bound mysql-cluster/datadir-mycluster-0 local-path 18d
persistentvolume/pvc-30ded14b-d55b-490f-87ed-f51f1c6fd1f8 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-2 nfs-storageclass 93m
persistentvolume/pvc-33402b1c-8c54-47e0-ae33-2aef70ed0463 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs1-1 nfs-storageclass 93m
persistentvolume/pvc-77f02240-47ae-48ba-9fb7-35e6d35dab7a 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-cfg-1 nfs-storageclass 93m
persistentvolume/pvc-8cce3b0b-a823-4dff-b9cf-480f4480e4f0 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-1 nfs-storageclass 93m
persistentvolume/pvc-a6b9a807-a854-4ca6-93f9-4f679e421955 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-cfg-2 nfs-storageclass 93m
persistentvolume/pvc-b8f3bc27-af6f-4418-b256-be896a7b09ce 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-cfg-0 nfs-storageclass 94m
persistentvolume/pvc-c746bca6-2fd1-4d0d-a7a7-00633d5d50f1 2Gi RWO Delete Bound mysql-cluster/datadir-mycluster-1 local-path 18d
persistentvolume/pvc-d008eb7f-2e0b-4f3d-a49f-b73d4d524e49 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs1-2 nfs-storageclass 92m
persistentvolume/pvc-dce20a6f-ec48-4a9d-b907-4a32e171db87 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs1-0 nfs-storageclass 94m
persistentvolume/pvc-ec5211d2-8390-48ed-aa1f-a802aedd1a39 3Gi RWO Delete Bound psmdb/mongod-data-yoojh5099-rs0-0 nfs-storageclass 94m
# mongos 라우터 접속 서비스 정보 확인
root@rook-01:~/mongodb# kubectl get svc,ep $MYNICK-mongos
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/yoojh5099-mongos ClusterIP 10.103.197.163 <none> 27017/TCP 93m
NAME ENDPOINTS AGE
endpoints/yoojh5099-mongos 10.244.125.241:27017,10.244.140.223:27017,10.244.155.124:27017 93m
# [터미널1] 클러스터 접속(ADMIN_USER)
root@rook-01:~/mongodb# kubectl exec ds/myclient -it -- mongo --quiet "mongodb://userAdmin:userAdmin123456@$MYNICK-mongos.psmdb.svc.cluster.local/admin?ssl=false"
mongos> db
admin
mongos> show dbs
admin 0.000GB
config 0.004GB
mongos> db.createUser({user: "doik" , pwd: "qwe123" , roles: [ "userAdminAnyDatabase", "dbAdminAnyDatabase","readWriteAnyDatabase"]})
Successfully added user: {
"user" : "doik",
"roles" : [
"userAdminAnyDatabase",
"dbAdminAnyDatabase",
"readWriteAnyDatabase"
]
}
# 샤드 클러스터 상태 확인 : 기본 정보, 샤드 정보, 밸런서 정보, 샤딩 설정이 된 컬렉션 정보, 청크 정보 등 출력
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("654dc58e07e083766e790112")
}
shards:
{ "_id" : "rs0", "host" : "rs0/yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017,yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017,yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017", "state" : 1, "topologyTime" : Timestamp(1699595812, 6) }
{ "_id" : "rs1", "host" : "rs1/yoojh5099-rs1-0.yoojh5099-rs1.psmdb.svc.cluster.local:27017,yoojh5099-rs1-1.yoojh5099-rs1.psmdb.svc.cluster.local:27017,yoojh5099-rs1-2.yoojh5099-rs1.psmdb.svc.cluster.local:27017", "state" : 1, "topologyTime" : Timestamp(1699595813, 5) }
active mongoses:
"6.0.9-7" : 3
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "config", "primary" : "config", "partitioned" : true }
config.system.sessions
shard key: { "_id" : 1 }
unique: false
balancing: true
chunks: