이 새로운 몽구스 기능은 MongoDB 쓰기를 최대 2.6배까지 향상시킬 수 있습니다.

거의 항상 백엔드 == 데이터베이스



일반적인 백엔드 애플리케이션의 가장 중요한 측면 중 하나가 사용자 대면 애플리케이션과 데이터베이스 사이의 좋은 계층 역할을 한다는 것은 비밀이 아닙니다.

즉, 데이터베이스를 마스터하고 성능을 최적화하면 수십만 명의 사용자를 동시에 처리할 수 있는 백엔드 앱과 처음 몇 백 명의 실제 사용자를 차단하는 애플리케이션 간의 차이를 만들 수 있습니다.

성능 향상을 위한 대량 작업



상당한 성능 향상을 가져올 수 있는 대중적이고 구현하기 쉬운 기술 중 하나는 작업을 함께 그룹화하여 백엔드 애플리케이션과 데이터베이스 또는 외부 서비스 간의 왕복 횟수를 줄이는 것입니다.

예를 들어 데이터베이스에서 100개의 주문을 가져오려면 다음과 같이 할 수 있습니다.
  • 100개의 서로 다른 단일 쿼리를 생성하여 백엔드와 데이터베이스 간에 100번의 네트워크 왕복이 발생합니다.
  • 한 번에 100명의 사용자를 모두 가져오는 1개의 쿼리를 생성하여 단일 네트워크 왕복을 생성합니다.

  • 데이터 크기가 같더라도 네트워크 왕복 횟수가 적을수록 훨씬 빠릅니다. 네트워크 왕복 횟수 외에 그룹화 작업을 통해 데이터베이스가 내부적으로 최적화할 수 있습니다. 최적화의 한 예는 인덱스 조회 횟수를 줄이는 것입니다.

    Model.bulkSave(...)를 사용하는 몽구스



    mongoose v5.13.0에서는 각 작업을 개별적으로 전송하는 대신 대량으로 여러 쓰기를 전송하여 이 기술을 활용하는 기능Model.bulkSave(...)을 추가했습니다. 이 기능은 내부적으로 기본 MongoDBbulkWrite(...)를 활용합니다.
    좋은 소식은 이러한 성능 이점을 얻기 위해 기존 코드를 최소한으로 변경하도록 API가 의도적으로 설계되었다는 것입니다.

    100명의 사용자가 있고 각 사용자에 대해 카트를 찾고 싶은 경우 데이터베이스에 카트가 없으면 새 카트를 만들 수 있습니다. 두 가지 방법 중 하나로 수행

    변종 A) 다음 코드 스니펫은 각 카트에 대해 데이터베이스에 하나의 명령updateOne/insertOne을 전송합니다.

    const users = await User.find({ cityId: 1 });
    await Promise.all(users.map(async function (user){
      let cart = await  Cart.findOne({ userId: user._id });
      if (!cart) {
        cart = new Cart({ userId:user._id });
      }
    
      cart.itemsIds.addToSet(item._id);
      await cart.save();
    }));
    


    변형 B) 다음은 위의 코드 스니펫을 use bulkSave(...) 로 변환하여 저장하려는 문서 수에 관계없이 단일 데이터베이스 명령이 되는 방법입니다.

    const users = await User.find({ cityId: 1 });
    const carts = await Promise.all(users.map(async function (user){
      let cart = await  Cart.findOne({ userId: user._id });
      if (!cart) {
        cart = new Cart({ userId:user._id });
      }
    
      cart.itemsIds.addToSet(item._id);
      // instead of saving each cart individually
      // we'll return them now and save them all in bulk later
      return cart;
    }));
    
    
    // calls Cart.bulkWrite under the hood
    const writeResult = await Cart.bulkSave(carts); 
    


    첫 번째 예는 데이터베이스에 N개의 작업을 전송하여 연결에 과도한 로드를 생성하는 반면 두 번째 예는 단일 작업을 전송합니다.

    성능 비교:



    Model.bulkSave(...) 은 일반 Document#save(...) 보다 ~3배 빠를 수 있습니다. 직접 테스트하려면 이 코드gist에서 코드를 실행하세요.



    bulkSave 를 사용하는 경우와 save 를 사용하는 경우는 언제입니까?



    따라서 항상 bulkSave보다 save를 사용해야 합니까?
    MongoDB는 일괄 쓰기로 보낼 수 있는 데이터 크기a limit(배치당 작업 100,000개)를 가지고 있습니다. 안전을 위해 한 번에 10,000개의 문서를 보내면서도chunk 대량 저장의 상당한 성능 이점을 얻을 수 있습니다.

    일반적으로 10,000개 미만의 문서를 처리하는 경우 항상 bulkSave를 사용하는 것이 안전해야 합니다. 그렇지 않으면 문서를 한 번에 10,000개 처리하도록 청크 처리해야 합니다.
    bulkSave 에 대해 어떻게 생각하세요?
    응용 프로그램에서 사용하시겠습니까?
    시간이 지남에 따라 유용하다고 생각한 다른 성능 기술은 무엇입니까?

    댓글로 알려주세요!

    좋은 웹페이지 즐겨찾기