본문 바로가기

FrontEnd

TypeORM 스터디 : QueryBuilder 3편 - 캐싱

반응형

 

typeorm

 

1편 보기

 

TypeORM 스터디 : QueryBuilder 1편 - CRUD 기본

TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova a..

itchallenger.tistory.com

2편 보기

 

TypeORM 스터디 : QueryBuilder 2편 - CRUD 심화

TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova a..

itchallenger.tistory.com

 

QueryBuilder methods 캐시 가능 메서드: getMany, getOne, getRawMany, getRawOne and getCount.

Repository methods 캐시 가능 메서드 : find, findAndCount, findByIds, and count.

캐시를 적용하려면 커넥션 옵션에서 enable 해야함

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: true // here
}

// 글로벌 캐시 유효시간 설정. 디폴트는 1000
{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        duration: 30000 // 30 seconds
    }
}

캐시 활성화 시 데이터베이스 스키마를 동기화해야 한다.

// 쿼리빌더 아무 쿼리나 캐시하기
const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache(true) // here
    .getMany();
    
// 레포지토리 쿼리 캐시하기
const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: true
    });

기본 캐시 시간 설정은 1000ms임. 즉 1초

3초동안 해당 쿼리 요청을 1억번 해도 실제 쿼리는 3번 날라감

반대로 1초 내에 insert,update 하고 select하면 1초 동안은 업데이트 내용을 갱신안함

// 쿼리 빌더
const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache(60000) // 1 minute으로 시간 조절
    .getMany();

// 레포지토리 패턴
const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: 60000
    });

캐시 ID로 맘대로 invalidate 시키기

// 캐시 아이디와 유효시간 : QB
const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache("users_admins", 25000)
    .getMany();
    
// 캐시 아이디와 유효시간 : 레포
const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: {
            id: "users_admins",
            milliseconds: 25000
        }
    });
    
    
// 이렇게 하면 새 사용자를 삽입할 때 캐시된 결과를 지우는 것과 같이 캐시를 세부적으로 제어할 수 있습니다.
await connection.queryResultCache.remove(["users_admins"]);

기본적으로 TypeORM은 query-result-cache라는 별도의 테이블을 사용하고 모든 쿼리와 결과를 거기에 저장합니다.

테이블 이름은 설정가능함. tableName 속성에 다른 값을 지정하여 변경할 수 있습니다.

// 내부 캐시 테이블 컨피그
{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        type: "database",
        tableName: "configurable-table-query-result-cache"
    }
}

// 레디스로 캐시 테이블 이동하기. ioredis도 가능
{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        type: "redis",
        options: {
            host: "localhost",
            port: 6379
        }
    }
}

// options는 IORedis 옵션으로 사용할 수 있음
// IORedis의 클러스터 기능을 사용하여 redis-cluster에 연결하려는 경우.
{
    type: "mysql",
    host: "localhost",
    username: "test",
    cache: {
        type: "ioredis/cluster",
        options: {
            startupNodes: [
                {
                    host: 'localhost',
                    port: 7000,
                },
                {
                    host: 'localhost',
                    port: 7001,
                },
                {
                    host: 'localhost',
                    port: 7002,
                }
            ],
            options: {
                scaleReads: 'all',
                clusterRetryStrategy: function (times) { return null },
                redisOptions: {
                    maxRetriesPerRequest: 1
                }
            }
        }
    }
}

// Options에 IOREDIS 클러스터 구성만 입력하여 사용하는 것도 가능
{
    ...
    cache: {
        type: "ioredis/cluster",
        options: [
            {
                host: 'localhost',
                port: 7000,
            },
            {
                host: 'localhost',
                port: 7001,
            },
            {
                host: 'localhost',
                port: 7002,
            }
        ]
    },
    ...
}

기본 제공 캐시 공급자가 요구 사항을 충족하지 않는 경우 QueryResultCache 인터페이스를 구현하는 새 개체를 반환해야 하는 공급자 팩토리 함수를 사용하여 자체 캐시 공급자를 지정할 수도 있습니다.

(인메모리 캐시 등...)

잘 안쓸것 같은 기능임.

// 클래스 정의
class CustomQueryResultCache implements QueryResultCache {
    constructor(private connection: Connection) {}
    ...
}

// 사용
{
    ...
    cache: {
        provider(connection) {
            return new CustomQueryResultCache(connection);
        }
    }
}

 

캐시 오류를 무시하고 캐시 오류의 경우 쿼리가 데이터베이스로 전달되도록 하려면 ignoreErrors 옵션을 사용할 수 있습니다.

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        type: "redis",
        options: {
            host: "localhost",
            port: 6379
        },
        ignoreErrors: true
    }
}

cli에서 typeorm cache:clear 를 입력해 캐시 초기화 가능

 

참고  : 

TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.

 

TypeORM - Amazing ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server,

 

typeorm.io

 

반응형