Docs Menu
Docs Home
/ /
Atlas 아키텍처 센터
/

Atlas 지연 시간 감소 지침

다음 섹션에는 Atlas 배포서버 에서 지연 시간 줄이기 위해 선택할 수 있는 구성 옵션이 나열되어 있습니다.

물리적 거리는 지연 시간의 주요 원인입니다. 사용자와 애플리케이션 간 거리, 애플리케이션과 데이터 간 거리, 클러스터 노드 간 거리는 모두 시스템 지연 시간과 애플리케이션 성능에 영향을 미칩니다.

읽기 및 쓰기 (write) 작업의 지연 시간 줄이려면 애플리케이션 과 데이터를 지리적으로 사용자에게 더 가깝게 배치하는 것이 중요합니다. 데이터 보유 Atlas 노드는 데이터베이스의 데이터를 저장 하고 읽기 및 쓰기 (write) 작업을 처리하다 Atlas cluster 내의 서버 노드입니다. 애플리케이션 사용자의 더 빠른 데이터 액세스 지원 하려면 데이터를 포함하는 Atlas 노드를 대다수의 애플리케이션 사용자와 지리적으로 가까운 cloud 제공자 리전에 배포 .

애플리케이션 사용자가 여러 지역(예: 미국과 유럽)에 분산된 있는 경우, 각 지역에서 하나 이상의 리전에 배포 각 위치 의 사용자 지연 시간 줄이는 것이 좋습니다. 멀티 리전 배포에 대해 자세히 학습 멀티 리전 배포 패러다임을 참조하세요.

데이터가 지역별로 나누어져 각 지역의 사용자가 서로 다른 데이터 세트에 액세스 경우 각 지역의 사용자의 읽기 및 쓰기 (write) 성능을 최적화하기 위해 리전 또는 지역별로 데이터를샤드 할 수도 있습니다. 이 접근 방식을 사용하면 데이터 지역성을 보장하면서 대규모 데이터 세트와 높은 처리량 처리하다 할 수 있습니다.

복제는 프라이머리 노드 에서 세컨더리 노드로 데이터를 복사하는 것입니다. 다음 복제 구성 옵션을 조정하여 복제본 세트 에서 읽기 및 쓰기 (write) 작업의 지연 시간 최소화할 수 있습니다.

  • 쓰기 고려 수준: 쓰기 쓰기 고려 (write concern) 구성할 때 쓰기 (write) 지연 시간 과 쓰기 (write) 내구성 간에는 장단점이 있습니다. MongoDB의 기본값 전역 쓰기 고려 (write concern) 로 설정하다 majority 있으며, 각 쓰기 (write) 작업은 Atlas 작업이 완료되고 성공적인 클라이언트 확인하기 전에 복제본 세트 의 데이터 보유 투표 노드 과반수에 복제되어야 합니다. 쓰기 고려 (write concern) 높게 설정하면 쓰기 (write) 지연 시간 늘어나지만 쓰기 (write) 내구성이 향상되고 복제본 세트 페일오버 중 롤백이 방지됩니다.

  • 읽기 고려 및 읽기 설정: 읽기 고려 (read concern)읽기 설정 (read preference) 구성할 때 쿼리 지연 시간 , 데이터 가용성, 쿼리 응답의 일관성 간에는 장단점이 있습니다. MongoDB의 기본값 글로벌 읽기 고려 (read concern) 이며, 읽기 작업은 local 데이터가 다른 노드 간에 복제되는지 확인하기 위해 기다리지 않고 로컬 복제본 세트 의 하나의 노드 에서만 읽습니다. 이 노드 프라이머리 노드인지 세컨더리 노드 인지는 Atlas 기본값 으로(으)로 설정하는 읽기 설정 (read preference) primary 에 따라 결정됩니다. 이 기본값 읽기 고려 (read concern) 와 기본 설정 조합은 복제본 세트 의 최신 노드 에서 지연 지연 시간 이 가장 짧은 읽기에 최적화되지만, 프라이머리 노드의 데이터가 지속형 없고 작업이 진행되는 동안 잠재적으로 롤백될 수 있는 위험도 있습니다. 사용 가능한 프라이머리 노드 없는 경우 사용자는 페일오버 를 쿼리 할 수 없습니다.

    사용 가능한 primaryPreferred 프라이머리 노드 없거나 지리적으로 더 가까운 세컨더리 노드 가 있는 경우 읽기 작업이 세컨더리 노드 에서 읽을 수 있도록 읽기 읽기 설정 (read preference)(으)로 변경하면 세컨더리 노드가 다음과 같은 경우 오래된 데이터를 반환할 위험이 있습니다. 노드 최신 상태가 아닙니다. 쓰기 고려 (write concern) 늘려 더 많은 세컨더리 노드를 최신 상태로 유지하면 이러한 위험을 완화할 수 있지만, 이렇게 하면 쓰기 (write) 지연 시간 늘어나는 단점이 있습니다.

    중요

    복제 지연 으로 인해 세컨더리 노드 오래된 데이터를 반환할 가능성이 있다는 점에 유의하세요.

  • 쿼리 시간 제한: 배포서버 에 글로벌 및 작업 수준 쿼리 시간 제한을 설정하다 애플리케이션 이 시간이 초과되기 전에 응답을 기다리는 시간을 줄일 수 있습니다. 이렇게 하면 진행 중인 쿼리가 장기간 배포서버 성능에 부정적인 영향을 미치는 것을 방지할 수 있습니다.

  • 노드 투표 우선 순위: 복제본 세트 투표 중에 기본 members[n].priority 데이터 센터 의 노드가 대체 데이터 센터 의 노드보다 먼저 프라이머리 선출될 가능성을 높이려면 대체 데이터 센터 의 노드 us-east-1 중 를 다음과 같이 설정하다 수 있습니다. 프라이머리 데이터 센터 의 us-west-1 노드보다 낮습니다. 예시 를 들어 AWS 리전(버지니아 북부) 및(캘리포니아 us-west-1 북부)에 클러스터 배포 사용자의 대부분이 캘리포니아에 있는 경우, AWS 리전에서 노드의 우선 순위를 지정할 수 있습니다. } (캘리포니아 북부) 리전 사용하여 프라이머리 노드 가 지리적으로 항상 대다수의 사용자와 가깝고 최소한 지연 시간 으로 읽기 및 쓰기 (write) 작업에 응답할 수 있도록 보장합니다.

  • 미러링된 읽기: 미러링된 읽기는 장애 후 프라이머리 투표의 영향을 줄이기 위해 세컨더리 노드의 캐시를 사전 예열합니다. 자세한 내용은 미러링된 읽기를 참조하세요.

요구 사항에 가장 적합한 복제 구성을 구현하는 방법에 대한 자세한 지침 MongoDB의 전문 서비스 문의 .

다음 네트워크 연결 옵션을 사용하여 보안을 강화하고 지연 시간 더욱 줄일 수 있습니다.

애플리케이션 이 데이터에 액세스하는 속도가 지연 시간 에 영향을 미칩니다. 우수한 데이터 모델링 및 쿼리 최적화는 데이터 액세스 속도를 향상시킬 수 있습니다. 예시 를 들어 다음을 수행할 수 있습니다.

  • 문서 크기 줄이기: 네트워크를 통해 전송되는 데이터의 양을 줄이기 위해 필드 이름과 값 길이를 줄이는 것이 좋습니다.

  • 쿼리 패턴 최적화: 인덱스를 효과적으로 사용하여 여러 리전에서 읽어야 하는 데이터의 양을 최소화합니다.

Atlas 다양한 리전의 지연 시간 지표 관찰할 수 있는 실시간 성능 패널 (실시간 성능 패널) 을 제공합니다. 애플리케이션 수준 모니터링 구현 애플리케이션 과 주고받는 엔드 투 엔드 지연 시간 추적 수도 있습니다. 최종 프로덕션 배포서버 전에 지연 시간 병목 현상을 식별하고 주소 위해 다양한 멀티 리전 시나리오 에서 성능 테스트를 수행하는 것이 좋습니다.

배포서버 모니터링 에대해 자세히 학습 Atlas 모니터링 및 경고에 대한 지침을 참조하세요.

가능하면 애플리케이션의 프로그래밍 언어 에 맞는 최신 운전자 버전을 기반으로 구축된 연결 방법을 사용하는 것이 좋습니다. Atlas 애플리케이션 제공하는 기본값 연결 문자열 연결 문자열 연결 문자열 것이 배포서버 .

엔터프라이즈 수준 애플리케이션 배포의 경우 운영 지연 시간 최소화하면서 사용자 수요를 충족하도록 연결 풀 설정을 조정하는 것이 특히 중요합니다. 예시 들어 및 옵션을 사용하여 대부분의 minPoolSize maxPoolSize 데이터베이스 클라이언트 연결이 열리는 방법과 시기를 조정하여 관련 네트워크 오버헤드 와 함께 발생하는 지연 시간 급증을 방지하거나 계획할 수 있습니다.

이러한 설정을 구성할 수 있는 범위는 배포서버 아키텍처에 따라 다릅니다. 예시 들어, 애플리케이션 배포서버 AWS Lambda 와 같은 단일 스레드 리소스를 활용하는 경우, 애플리케이션 하나의 클라이언트 연결만 열고 사용할 수 있습니다. 연결 풀 만들고 사용하는 방법과 위치, 연결 풀 설정을 지정하는 위치에 대한 자세한 학습 은 연결 풀 개요를 참조하세요.

다음 샘플 애플리케이션 데이터 작업 지연 시간 줄이기 위해 이 페이지에 주요 권장 사항을 제공합니다.

  • 재시도 가능한 쓰기, 대다수 쓰기 고려 및 기본 읽기 고려와 함께 Atlas에서 제공하는 연결 문자열을 사용합니다.

  • maxTimeMS 메서드를 사용하여 optime 제한을 지정합니다. maxTimeMS 설정 방법에 대한 지침은 해당 드라이버 설명서를 참조하세요.

  • 키 중복 및 시간 초과에 대한 오류를 처리합니다.

이 애플리케이션 클라이언트가 사용자 레코드를 생성하거나 나열할 수 있는 HTTP API 입니다. GET 및 POST 요청을 수락하는 엔드포인트 http://localhost:: 를 노출합니다.3000

메서드
엔드포인트
설명

GET

/users

users 컬렉션에서 사용자 이름 목록을 가져옵니다.

POST

/users

요청 본문에 name이 필요합니다. users 컬렉션에 새 사용자를 추가합니다.

참고

다음 서버 애플리케이션 프로젝트를 실행 하기 전에 프로젝트 에 종속성으로 추가해야 하는 NanoHTTPDJSON 사용합니다.

1// File: App.java
2
3import java.util.Map;
4import java.util.logging.Logger;
5
6import org.bson.Document;
7import org.json.JSONArray;
8
9import com.mongodb.MongoException;
10import com.mongodb.client.MongoClient;
11import com.mongodb.client.MongoClients;
12import com.mongodb.client.MongoCollection;
13import com.mongodb.client.MongoDatabase;
14
15import fi.iki.elonen.NanoHTTPD;
16
17public class App extends NanoHTTPD {
18 private static final Logger LOGGER = Logger.getLogger(App.class.getName());
19
20 static int port = 3000;
21 static MongoClient client = null;
22
23 public App() throws Exception {
24 super(port);
25
26 // Replace the uri string with your MongoDB deployment's connection string
27 String uri = "<atlas-connection-string>";
28 client = MongoClients.create(uri);
29
30 start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
31 LOGGER.info("\nStarted the server: http://localhost:" + port + "/ \n");
32 }
33
34 public static void main(String[] args) {
35 try {
36 new App();
37 } catch (Exception e) {
38 LOGGER.severe("Couldn't start server:\n" + e);
39 }
40 }
41
42 @Override
43 public Response serve(IHTTPSession session) {
44 StringBuilder msg = new StringBuilder();
45 Map<String, String> params = session.getParms();
46
47 Method reqMethod = session.getMethod();
48 String uri = session.getUri();
49
50 if (Method.GET == reqMethod) {
51 if (uri.equals("/")) {
52 msg.append("Welcome to my API!");
53 } else if (uri.equals("/users")) {
54 msg.append(listUsers(client));
55 } else {
56 msg.append("Unrecognized URI: ").append(uri);
57 }
58 } else if (Method.POST == reqMethod) {
59 try {
60 String name = params.get("name");
61 if (name == null) {
62 throw new Exception("Unable to process POST request: 'name' parameter required");
63 } else {
64 insertUser(client, name);
65 msg.append("User successfully added!");
66 }
67 } catch (Exception e) {
68 msg.append(e);
69 }
70 }
71
72 return newFixedLengthResponse(msg.toString());
73 }
74
75 static String listUsers(MongoClient client) {
76 MongoDatabase database = client.getDatabase("test");
77 MongoCollection<Document> collection = database.getCollection("users");
78
79 final JSONArray jsonResults = new JSONArray();
80 collection.find().forEach((result) -> jsonResults.put(result.toJson()));
81
82 return jsonResults.toString();
83 }
84
85 static String insertUser(MongoClient client, String name) throws MongoException {
86 MongoDatabase database = client.getDatabase("test");
87 MongoCollection<Document> collection = database.getCollection("users");
88
89 collection.insertOne(new Document().append("name", name));
90 return "Successfully inserted user: " + name;
91 }
92}

참고

다음 서버 애플리케이션은 Express를 사용하며, 이를 실행하려면 프로젝트에 종속성으로 추가해야 합니다.

1const express = require('express');
2const bodyParser = require('body-parser');
3
4// Use the latest drivers by installing & importing them
5const MongoClient = require('mongodb').MongoClient;
6
7const app = express();
8app.use(bodyParser.json());
9app.use(bodyParser.urlencoded({ extended: true }));
10
11const uri = "mongodb+srv://<db_username>:<db_password>@cluster0-111xx.mongodb.net/test?retryWrites=true&w=majority";
12
13const client = new MongoClient(uri, {
14 useNewUrlParser: true,
15 useUnifiedTopology: true
16});
17
18// ----- API routes ----- //
19app.get('/', (req, res) => res.send('Welcome to my API!'));
20
21app.get('/users', (req, res) => {
22 const collection = client.db("test").collection("users");
23
24 collection
25 .find({})
26 .maxTimeMS(5000)
27 .toArray((err, data) => {
28 if (err) {
29 res.send("The request has timed out. Please check your connection and try again.");
30 }
31 return res.json(data);
32 });
33});
34
35app.post('/users', (req, res) => {
36 const collection = client.db("test").collection("users");
37 collection.insertOne({ name: req.body.name })
38 .then(result => {
39 res.send("User successfully added!");
40 }, err => {
41 res.send("An application error has occurred. Please try again.");
42 })
43});
44// ----- End of API routes ----- //
45
46app.listen(3000, () => {
47 console.log(`Listening on port 3000.`);
48 client.connect(err => {
49 if (err) {
50 console.log("Not connected: ", err);
51 process.exit(0);
52 }
53 console.log('Connected.');
54 });
55});

참고

다음 웹 애플리케이션 FastAPI를 사용합니다. 새 애플리케이션 만들려면 FastAPI 샘플 파일 구조를 사용합니다.

1# File: main.py
2
3from fastapi import FastAPI, Body, Request, Response, HTTPException, status
4from fastapi.encoders import jsonable_encoder
5
6from typing import List
7from models import User
8
9import pymongo
10from pymongo import MongoClient
11from pymongo import errors
12
13# Replace the uri string with your |service| connection string
14uri = "<atlas-connection-string>"
15db = "test"
16
17app = FastAPI()
18
19@app.on_event("startup")
20def startup_db_client():
21 app.mongodb_client = MongoClient(uri)
22 app.database = app.mongodb_client[db]
23
24@app.on_event("shutdown")
25def shutdown_db_client():
26 app.mongodb_client.close()
27
28##### API ROUTES #####
29@app.get("/users", response_description="List all users", response_model=List[User])
30def list_users(request: Request):
31 try:
32 users = list(request.app.database["users"].find().max_time_ms(5000))
33 return users
34 except pymongo.errors.ExecutionTimeout:
35 raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="The request has timed out. Please check your connection and try again.")
36
37@app.post("/users", response_description="Create a new user", status_code=status.HTTP_201_CREATED)
38def new_user(request: Request, user: User = Body(...)):
39 user = jsonable_encoder(user)
40 try:
41 new_user = request.app.database["users"].insert_one(user)
42 return {"message":"User successfully added!"}
43 except pymongo.errors.DuplicateKeyError:
44 raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Could not create user due to existing '_id' value in the collection. Try again with a different '_id' value.")

돌아가기

확장성

이 페이지의 내용