AWS Lambda로 연결 관리
모범 사례
다음 권장사항을 사용하여 AWS Lambda와 Atlas 간의 연결을 올바르게 관리하세요.
AWS Lambda 핸들러 함수 외부에서 MongoDB 서버에 대한 클라이언트를 정의합니다.
함수를 호출할 때마다 새
MongoClient
객체를 정의하지 않습니다. 이로 인해 드라이버가 각 함수 호출에 대해 새 데이터베이스 연결을 생성하게 됩니다. 이 경우 비용이 많이 들 수 있고 그 결과 애플리케이션이 데이터베이스 연결 제한을 초과할 수 있습니다. 새MongoClient
를 정의하는 경우 다음과 같이 수행해야 합니다.MongoClient
객체를 한 번 생성합니다.함수가 함수 호출에서
MongoClient
를 재사용할 수 있도록 객체를 저장합니다.
연결 예시는 기존 데이터베이스 연결을 재사용하여 데이터베이스와의 통신 속도를 높이고 애플리케이션 트래픽과 관련하여 데이터베이스에 대한 연결 수를 합리적인 수준으로 유지합니다.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 사항은 연결 옵션을 참조하세요.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 사항은 연결 옵션을 참조하세요.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 사항은 연결 옵션을 참조하세요.
처리기가 콜백을 마지막 인자로 사용하는 경우 AWS Lambda 컨텍스트 객체의
callbackWaitsForEmptyEventLoop
속성을 false로 설정하십시오.context.callbackWaitsForEmptyEventLoop = false; 이를 통해 MongoDB database 연결을 닫을 필요 없이 Lambda 함수가 호출자에게 결과를 반환할 수 있습니다. 비동기 핸들러에는 이 속성을 설정할 수 없습니다.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 사항은 연결 옵션을 참조하세요.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 내용은 MongoDB에 연결하기 위한 도구를 참조하세요.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 내용은 URI 옵션을 참조하세요.
샤드가 많은 샤딩된 클러스터에 연결하는 Lambda 함수가 있는 경우 성능 문제가 발생할 수 있습니다. 예를 들어, 샤딩된 클러스터가 10개인 경우 드라이버는 기본적으로 30개의
mongos
인스턴스 모두에 연결합니다. 연결 문자열에서srvMaxHosts
옵션을 사용하여 드라이버가 연결하는 최대 호스트 수를 설정할 수 있습니다. 드라이버 성능을 개선하려면srvMaxHosts=3
을(를) 설정합니다. 예를 들면 다음과 같습니다.mongodb+srv://<db_username>:<db_password>@<clusterName>.mongodb.net/?retryWrites=true&w=majority&srvMaxHosts=3 자세한 사항은 연결 옵션을 참조하세요.
Atlas 클러스터에 대한 네트워크 액세스를 제한합니다.
Atlas 클러스터와 AWS Lambda 함수 간의 네트워크 피어링 연결 을 사용하거나 비공개 엔드포인트 를 사용하여 비공개 네트워킹을 통해 Atlas 클러스터에 연결해 IP액세스 목록 에서 비공개 IP 주소만 허용할 수 있습니다.
비공개 네트워킹을 사용하지 않는 경우, 매핑된 탄력적 IP 주소로 NAT 게이트웨이를 통해 Atlas 클러스터에 연결하는 것을 권장합니다. 그렇지 않으면 모든 IP 주소(0.0.0.0/0)가 서비스 클러스터에 액세스할 수 있도록 허용해야 합니다.
경고
IP 액세스 목록에
0.0.0.0/0
추가하면 공용 인터넷의 어디에서든지 cluster에 액세스할 수 있습니다. 어디에서든 액세스를 허용하는 경우 데이터베이스 사용자 에 대해 강력한 자격 증명을 사용해야 합니다.
유휴 시간 1분 후 자동으로 연결을 종료하려면 maxIdleTimeMS를
60000
으로 설정합니다.maxIdleTimeMS
를 조정하면 서버리스 함수에서 시간 초과 오류 발생을 줄이는 데 유용할 수 있습니다.
통합 AWS 액세스를 설정하고 가능한 경우 AWS IAM 인증을 사용하세요.
Lambda에서 자격 증명을 하드코딩하는 대신 AWS IAM 역할을 사용하여 Atlas 클러스터에 연결할 수 있습니다. AWS Lambda 환경에 액세스하는 모든 사람은 하드코딩된 자격 증명을 볼 수 있는데, 이로 인해 보안 위험이 발생할 수 있습니다. AWS IAM 인증을 사용하면 Atlas가 가정된 IAM 역할을 통해 AWSLambda에 액세스하므로 연결 문자열에 자격 증명이 필요하지 않습니다.
Atlas는 MongoDB 버전 5.0 이상을 실행하는 클러스터에 대해 AWS IAM 인증을 지원합니다. 클러스터가 요구 사항을 충족하는 경우 Lambda 연결에 AWS IAM 인증을 사용할 것을 강력히 권장합니다.
Lambda 함수에 할당되는 메모리 양의 기본값은 128MB입니다. Lambda 함수에 할당되는 메모리 양을 128MB ~ 10,240MB로 구성할 수 있습니다. 메모리를 충분히 할당했는지 확인합니다. 메모리를 늘려 사용 가능한 가상 CPU의 양을 늘리고 MongoDB 드라이버 성능을 개선합니다. 자세히 알아보려면 메모리 및 컴퓨팅 성능을 참조하세요.
AWS_STS_REGIONAL_ENDPOINTS 및 AWS_REGION 환경 변수를 설정합니다.
연결 예시
Amazon Web Services Amazon Web Services IAM 인증
string username = Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID"); string password = Environment.GetEnvironmentVariable("AWS_SECRET_ACCESS_KEY"); string awsSessionToken = Environment.GetEnvironmentVariable("AWS_SESSION_TOKEN"); var awsCredentials = new MongoCredential("MONGODB-AWS", new MongoExternalIdentity(username), new PasswordEvidence(password)) .WithMechanismProperty("AWS_SESSION_TOKEN", awsSessionToken); var mongoUrl = MongoUrl.Create($"<MONGODB_URI>"); var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl); mongoClientSettings.Credential = awsCredentials; mongoClientSettings.ServerApi = new ServerApi(ServerApiVersion.V1, strict: true); return new MongoClient(mongoClientSettings);
기타 인증
private static MongoClient MongoClient { get; set; } private static MongoClient CreateMongoClient() { var mongoClientSettings = MongoClientSettings.FromConnectionString($"<MONGODB_URI>"); mongoClientSettings.ServerApi = new ServerApi(ServerApiVersion.V1, strict: true); return new MongoClient(mongoClientSettings); } static ShareMongoClientLambdaHandler() { MongoClient = CreateMongoClient(); } public string HandleRequest(ILambdaContext context) { var database = MongoClient.GetDatabase("db"); var collection = database.GetCollection<BsonDocument>("coll"); var result = collection.Find(FilterDefinition<BsonDocument>.Empty).First(); return result.ToString(); }
var client, err = mongo.Connect(context.TODO(), options.Client().ApplyURI(os.Getenv("MONGODB_URI"))) func HandleRequest(ctx context.Context) error { if err != nil { return err } return client.Ping(context.TODO(), nil) }
public class ExampleAwsLambdaHandler implements RequestHandler<String, String> { private final MongoClient client; public ExampleAwsLambdaHandler() { client = MongoClients.create(System.getenv("MONGODB_URI")); } public String handleRequest(final String input, final Context context) { return client.getDatabase("admin").runCommand(new Document("ping", 1)).toJson(); } }
Amazon Web Services Amazon Web Services IAM 인증
const { MongoClient } = require('mongodb'); // Get the URI for the cluster then set AWS_ACCESS_KEY_ID as the username in the // URI and AWS_SECRET_ACCESS_KEY as the password, then set the appropriate auth // options. Note that MongoClient now auto-connects so no need to store the connect() // promise anywhere and reference it. const client = new MongoClient(process.env.MONGODB_URI, { auth: { username: process.env.AWS_ACCESS_KEY_ID, password: process.env.AWS_SECRET_ACCESS_KEY }, authSource: '$external', authMechanism: 'MONGODB-AWS' }); module.exports.handler = async function () { const databases = await client.db('admin').command({ listDatabases: 1 }); return { statusCode: 200, databases: databases }; };
기타 인증
const { MongoClient } = require('mongodb'); // MongoClient now auto-connects so no need to store the connect() // promise anywhere and reference it. const client = new MongoClient(process.env.MONGODB_URI); module.exports.handler = async function () { const databases = await client.db('admin').command({ listDatabases: 1 }); return { statusCode: 200, databases: databases }; };
import os from pymongo import MongoClient client = MongoClient(host=os.environ["MONGODB_URI"]) def lambda_handler(event, context): return client.db.command("ping")
Amazon Web Services Amazon Web Services IAM 인증
# Require the driver library. require "mongo" # Create a Mongo::Client instance using AWS IAM authentication. # CRITICAL: You must create the client instance outside the handler # so that the client can be reused across function invocations. client = Mongo::Client.new([ENV.fetch("MONGODB_HOST")], auth_mech: :aws, user: ENV.fetch("AWS_ACCESS_KEY_ID"), password: ENV.fetch("AWS_SECRET_ACCESS_KEY"), auth_mech_properties: { aws_session_token: ENV.fetch("AWS_SESSION_TOKEN"), }, database: ENV.fetch("MONGODB_DATABASE")) def lambda_handler(event:, context:) # Use the client to return the name of the configured database. client.database.name end
기타 인증
# Require the driver library. require "mongo" # Create a Mongo::Client instance. # CRITICAL: You must create the client instance outside the handler # so that the client can be reused across function invocations. client = Mongo::Client.new(ENV.fetch("MONGODB_URI")) def lambda_handler(event:, context:) # Use the client to return the name of the configured database. client.database.name end
AWS IAM 인증
use lambda_runtime::{service_fn, LambdaEvent}; use mongodb::{ bson::doc, options::{AuthMechanism, ClientOptions, Credential}, Client, }; use serde_json::Value; use tokio::sync::OnceCell; // Initialize a global static MongoDB Client with AWS authentication. The following environment // variables should also be set: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and, optionally, // AWS_SESSION_TOKEN. static MONGODB_CLIENT: OnceCell<Client> = OnceCell::const_new(); async fn get_mongodb_client() -> &'static Client { MONGODB_CLIENT .get_or_init(|| async { let uri = std::env::var("MONGODB_URI") .expect("MONGODB_URI must be set to the URI of the MongoDB deployment"); let mut options = ClientOptions::parse(&uri) .await .expect("Failed to parse options from URI"); let credential = Credential::builder() .mechanism(AuthMechanism::MongoDbAws) .build(); options.credential = Some(credential); Client::with_options(options).expect("Failed to create MongoDB Client") }) .await } // Runs a ping operation on the "db" database and returns the response. async fn handler(_: LambdaEvent<Value>) -> Result<Value, lambda_runtime::Error> { let client = get_mongodb_client().await; let response = client .database("db") .run_command(doc! { "ping": 1 }) .await?; let json = serde_json::to_value(response)?; Ok(json) } async fn main() -> Result<(), lambda_runtime::Error> { let service = service_fn(handler); lambda_runtime::run(service).await?; Ok(()) }
기타 인증
use lambda_runtime::{service_fn, LambdaEvent}; use mongodb::{bson::doc, Client}; use serde_json::Value; use tokio::sync::OnceCell; // Initialize a global static MongoDB Client. static MONGODB_CLIENT: OnceCell<Client> = OnceCell::const_new(); async fn get_mongodb_client() -> &'static Client { MONGODB_CLIENT .get_or_init(|| async { let uri = std::env::var("MONGODB_URI") .expect("MONGODB_URI must be set to the URI of the MongoDB deployment"); Client::with_uri_str(uri) .await .expect("Failed to create MongoDB Client") }) .await } // Runs a ping operation on the "db" database and returns the response. async fn handler(_: LambdaEvent<Value>) -> Result<Value, lambda_runtime::Error> { let client = get_mongodb_client().await; let response = client .database("db") .run_command(doc! { "ping": 1 }) .await?; let json = serde_json::to_value(response)?; Ok(json) } async fn main() -> Result<(), lambda_runtime::Error> { let service = service_fn(handler); lambda_runtime::run(service).await?; Ok(()) }