Connection Pool

Thread Pool에 이어지는 글이다.

Source code

https://github.com/teamsmiley/gitbook-sample/tree/main/ThreadTest

entity framework sample code

나는 mysql로 처리를 해보려고 한다. test디비를 만들고 blog테이블을 만들었다 항목은 url이 하나 있다.

dotnet add package Pomelo.EntityFrameworkCore.MySql --version 6.0.2
vi ValuesController.cs
using var connection = new MySqlConnection("server=192.168.1.21;User ID=root;Password=root;database=test;");
connection.Open();

using var command = connection.CreateCommand();
command.CommandText = "DO SLEEP(10);SELECT Url FROM Blogs;";

using var reader = command.ExecuteReader();
while (reader.Read())
{
  var url = reader.GetString(0);
  System.Console.WriteLine($"blog url {url}");
}

// Thread.Sleep(1000000); // Sleep for 10 seconds
Console.WriteLine("Thread completed. go back to the pool.");

코드를 실행하고 locust를 실행하자마자 다음과 같은 문제가 생긴다.

alt text

que가 계속 올라간다.

문서에 따르면 기본적으로 dbcontext는 connection pool을 사용하지 않는다.

https://learn.microsoft.com/en-us/ef/core/performance/advanced-performance-topics?tabs=with-di%2Cexpression-api-with-constant#dbcontext-pooling

alt text

AddDbContextPool를 사용해야한다. 기본적으로 connection pool은 1024개의 풀을 만든다. 이것은 설정을 통해서 변경할수 있다.

테스트 결과 mysql의 max_connection 갯수보다 많으면 thread가 죽는것을 알수있다

SHOW VARIABLES LIKE '%connect%';SHOW STATUS LIKE 'Threads_connected';
alt text

102개 이상의 커넥션을 안받는걸 알수 있다.

api는 error를 보낸다.

alt text

api를 멈추자.

그러나 현재 연결된 갯수는 줄어들지 않는다.

alt text

이것은 mysql의 wait_timeout이 8시간이기 때문이다. 8시간이 지나면 줄어들려나.

결과적으로 connect을 계속 늘리면 문제가 된다. 디비를 재시작해야하는경우까지 생길수 있다.

코드를 수정해보자.

// command.CommandText = "DO SLEEP(1000);SELECT Url FROM Blogs;";
command.CommandText = "SELECT Url FROM Blogs;";

문제없이 모든요청을 처리할수 있고 connect도 많이 추가되지 않는다

결론은 쿼리가 끝나면 커넥션이 자동으로 끊어지는걸 알수있다.

커넥션 풀을 사용하면 커넥션을 재사용할수 있고 커넥션을 더 빨리 얻을수 있다.

퍼포먼스

alt text

두배 이상의 커넥션 맺는 속도 향상을 얻을수 있다.

todo

다음은 redis를 해보자.

Last updated

Was this helpful?