Nodejs rawcache 高速缓存

Nodejs rawcache 高速缓存

nodejsrawcache 高速缓存

作者 : solq

blog :

git : https://github.com/solq360/springnodejs https://github.com/solq360/springnodejsExample.git

QQ群:9547527

RamCacheService.ts 缓存层服务
Accessor.ts 持久化处理器
Querier.ts 数据查询器
Entity.ts 元数据信息 未完成

以下代码比较旧,在做数据查询器的时候发现 mysql 驱动没有同步的接口,真恶心。为了给自己一个交代还是把功能做出来了 现在把功能共享出来,具体请看 git 源码 http://rawcache.springnodejs.com/

ts 目录 ts 源码 js 目录 ts 编译好的JS代码

Accessor.ts

/**数据持久化处理器*/
interface Accessor {
    /***保存实体*/
    save(name: EntityName, entity: Entity): void;
    /***更新实体*/
    update(name: EntityName, entity: Entity): void;
    /***加载实体*/
    load(name: EntityName, id: any): Entity;
    /***删除实体*/
    remove(name: EntityName, entity: Entity): void;
    /***执行持久化*/
    persister(name: EntityName): void;
}

/*定时 数据持久化处理器/ class TimerAccessor implements Accessor { //数据查询器 private querier: Querier; //持久化监听器 private persisterListeners: { [id: string]: any };

//保存队列
private saveQueue: { [id: string]: { [id: string]: Entity; }; } = {};
//删除队列
private removeQueue: { [id: string]: { [id: string]: any; } } = {};

public save(name: EntityName, entity: Entity): void {
    this.addSaveQueue(name, entity);
}
/***更新实体*/
public update(name: EntityName, entity: Entity): void {
    this.addSaveQueue(name, entity);
}
/***加载实体*/
public load(name: EntityName, id: any): Entity {
    var data: any = this.querier.findOne(name, id);
    return data;
}
/***删除实体*/
public remove(name: EntityName, entity: Entity): void {
    //直接删除
    this.querier.remove(name, entity.getId());
    this.addDelQueue(name, entity);
}
/***执行持久化*/
persister(name: EntityName): void {
    var key: string = name + '';

    /*
    var removeIds: { [id: string]: any; } = this.removeQueue[key];
    this.removeQueue[key] = {};
    for (var id in removeIds) {
        this.querier.remove(name, id);
    }
    removeIds = null;
    */

    var saveIds: { [id: string]: Entity; } = this.saveQueue[key];
    this.saveQueue[key] = {};
    for (var data in saveIds) {
        this.querier.save(name, data);
    }
    saveIds = null;
}

/**注册实体持久化监听器*/
public registerListener(name: EntityName, cacheConfig: CacheConfig): void {
    var key: string = name + '';
    var persisterListener: any = this.persisterListeners[key];
    var $this = this;
    if (persisterListener == null) {
        var value = name;
        persisterListener = setInterval(function() {
            $this.persister(value);
        }, cacheConfig.timeTirgger);
    }
}
public removeListener(name: EntityName): void {
    var key: string = name + '';
    var persisterListener: any = this.persisterListeners[key];
    if (persisterListener != null) {
        clearInterval(persisterListener);
        delete this.persisterListeners[key];
    }
}



/***构造方法*/
public static valueOf(querier: Querier): TimerAccessor {
    var result: TimerAccessor = new TimerAccessor();
    result.querier = querier;
    return result;
}

//private
private addSaveQueue(name: EntityName, entity: Entity): void {
    var key: string = name + "";
    var id: string = entity.getId();
    if (this.saveQueue[key] == null) {
        this.saveQueue[key] = {};
    }
    this.saveQueue[key][id] = entity;
}


private addDelQueue(name: EntityName, entity: Entity): void {
    var key: string = name + "";
    var id: string = entity.getId();

    if (this.saveQueue[key] == null) {
        return;
    }
    delete this.saveQueue[key][id];
    /*
   
    if (this.removeQueue[key] == null) {
        this.removeQueue[key] = {};
    }
    this.removeQueue[key][id] = 1;
    */
}

}

Querier .ts 实现未完成

/***查询器*/
interface Querier {
    /**保存数据**/
    save(name: EntityName, entity: Entity): void;
    /**查询指定数据**/
    findOne(name: EntityName, id: any): Entity;
    /**查询所有数据**/
    findAll(name: EntityName): Array<Entity>;
    /**查询指定数据**/
    find(name: EntityName, ...queryParams: Array<any>): Array<Entity>;
    /**删除数据**/
    remove(name: EntityName, id: any): void;
}
/***mysql*/
interface MySqlIConnection {
    query(sql: string, callback: (err: any, rows: any, fields: any) => void): void;
}
class MysqlQuerier implements Querier {
    /**查询SQL模板*/
    private static query_all_tpl: string = "SELECT * FROM {name}";

    /**数据库连接对象*/
    private connection: MySqlIConnection;


    save(name: EntityName, entity: Entity): void {

    }
    findOne(name: EntityName, id: any): any {
        return {};
    }
    findAll(name: EntityName): Array<Entity> {
        var result: Array<Entity> = [];

        var sql: string = MysqlQuerier.query_all_tpl;

        this.connection.query(sql, function(err, rows, fields) {
            if (err) throw err;
            for (var i in rows) {
                
            }
            console.log('value 2', rows);
        });
        return result;
    }
    find(name: EntityName, ...queryParams: Array<any>): Array<Entity> {
        return [];
    }

    remove(name: EntityName, id: any): void {

    }
    
    
    //private
    
    
}

declare var module: any;
module.exports = MysqlQuerier;

RamCacheService.ts

/***
高速缓存服务
不考虑加锁情况下
*/
class RamCacheService {
    //    constructor() {
    //        throw new Error("Cannot new this class");
    //    }
    private entityMetadata: EntityMetadata;
    
    private accessor: Accessor;
    private querier: Querier;
    
    private cacheData: { [id: string]: Entity; } = {};
    private addCacheData(entity: Entity) {
        var id: string = entity.getId();
        this.cacheData[id] = entity;
    }

    private getCacheData(id: any): Entity {
        return this.cacheData[id];
    }

    private removeCacheData(entity: Entity) {
        var id: string = entity.getId();
        delete this.cacheData[id];
    }

    private initCacheData(): void {
        var name = this.entityMetadata.entityName;
        var cacheConfig: CacheConfig = this.entityMetadata.cacheConfig;
        if (cacheConfig.initCacheConfig != null) {
            var initCacheConfig: InitCacheConfig = cacheConfig.initCacheConfig;
            var datas: Array<Entity>;
            switch (initCacheConfig.initType) {
                case InitCacheType.ALL:
                    datas = this.querier.findAll(name);
                    break;
                case InitCacheType.QUERY:
                    datas = this.querier.find(name, initCacheConfig.queryValue);
                    break;
                default:
                    return;
                    break;
            }
            for (var entity in datas) {
                this.addCacheData(entity);
            }
        }

    }

    /**公开方法 */
    /**构造 服务  */
    valueOf(accessor: Accessor, querier: Querier, entityMetadata: EntityMetadata): RamCacheService {
        var result: RamCacheService = new RamCacheService();
        result.accessor = accessor;
        result.querier = querier;
        result.entityMetadata = entityMetadata;
        result.initCacheData();
        return result;
    }
    /**加载或者创建实体 */
    loadOrCreate(id: any, callback: (id: any) => Entity): Entity {
        var resultEntity: Entity = this.getCacheData(id);
        if (resultEntity == null) {
            var name = this.entityMetadata.entityName;
            resultEntity = this.accessor.load(name, id);
        }

        if (resultEntity == null) {
            resultEntity = callback(id);
            this.save(resultEntity);
        }
        return resultEntity;
    }
    /**保存实体 */
    save(entity: Entity): void {
        var name = this.entityMetadata.entityName;
        this.accessor.save(name, entity);
        this.addCacheData(entity);
    }
    /**更新实体 */
    update(entity: Entity): void {
        this.save(entity);
    }
    /**删除实体 */
    remove(entity: Entity): void {
        var name = this.entityMetadata.entityName;
        this.accessor.remove(name, entity);
        this.removeCacheData(entity);
    }
    /**获取实体元数据 */
    getEntityMetadata(): EntityMetadata {
        return this.entityMetadata;
    }
}

declare var module: any;
module.exports = RamCacheService;

TestRamCache.js

var mysql = require('mysql');
var entity = require('./Entity');
var querier = require('./Querier');
var accessor = require('./Accessor');
var ramCacheService = require('./RamCacheService');

var connection = mysql.createConnection({
    host: 'localhost',
    port: 8585,
    database: 'test',
    user: 'root',
    password: '1212'
});
connection.connect();
 
var mysqlQuerier = querier.valueOf(connection);
var timerAccessor = accessor.valueOf(mysqlQuerier);

mysqlQuerier.findAll(EntityName.test, function (res) {
    // console.log(res);
});

_find();

function _find() {
    var startTime = new Date().getTime();
    timerAccessor.load(EntityName.test, 1, function (res) {
        return { id: 1 };
    }, function (res) {
        var endTime = new Date().getTime();
        console.log("find  time : ", (endTime - startTime));
        console.log(res);

        cache_find();
    });
}

function cache_find() {
    var startTime = new Date().getTime();
    timerAccessor.load(EntityName.test, 1, function (res) {
        return { id: 1 };
    }, function (res) {
        var endTime = new Date().getTime();
        console.log("find cache time : ", (endTime - startTime));
        console.log(res);
    });
}

Show Result

find  time :  9
{ id: 1, body: '2121' }
find cache time :  1
{ id: 1, body: '2121' }

至于ts 是什么有兴趣请看


10 回复

Nodejs Rawcache 高速缓存

作者: solq
博客:

Git:

QQ群: 9547527

文件结构

RamCacheService.ts: 缓存层服务
Accessor.ts: 持久化处理器
Querier.ts: 数据查询器
Entity.ts: 元数据信息(未完成)

示例代码

Accessor.ts
/** 数据持久化处理器 */
interface Accessor {
    /** 保存实体 */
    save(name: EntityName, entity: Entity): void;
    /** 更新实体 */
    update(name: EntityName, entity: Entity): void;
    /** 加载实体 */
    load(name: EntityName, id: any): Entity;
    /** 删除实体 */
    remove(name: EntityName, entity: Entity): void;
    /** 执行持久化 */
    persister(name: EntityName): void;
}

/** 定时数据持久化处理器 */
class TimerAccessor implements Accessor {
    private querier: Querier;
    private persisterListeners: { [id: string]: any };

    private saveQueue: { [id: string]: { [id: string]: Entity; } } = {};
    private removeQueue: { [id: string]: { [id: string]: any; } } = {};

    public save(name: EntityName, entity: Entity): void {
        this.addSaveQueue(name, entity);
    }

    public update(name: EntityName, entity: Entity): void {
        this.addSaveQueue(name, entity);
    }

    public load(name: EntityName, id: any): Entity {
        var data: any = this.querier.findOne(name, id);
        return data;
    }

    public remove(name: EntityName, entity: Entity): void {
        this.querier.remove(name, entity.getId());
        this.addDelQueue(name, entity);
    }

    public persister(name: EntityName): void {
        var key: string = name + '';

        var saveIds: { [id: string]: Entity; } = this.saveQueue[key];
        this.saveQueue[key] = {};
        for (var id in saveIds) {
            this.querier.save(name, saveIds[id]);
        }
    }

    public registerListener(name: EntityName, cacheConfig: CacheConfig): void {
        var key: string = name + '';
        var persisterListener: any = this.persisterListeners[key];
        var $this = this;
        if (persisterListener == null) {
            persisterListener = setInterval(function() {
                $this.persister(key);
            }, cacheConfig.timeTirgger);
        }
    }

    public removeListener(name: EntityName): void {
        var key: string = name + '';
        var persisterListener: any = this.persisterListeners[key];
        if (persisterListener != null) {
            clearInterval(persisterListener);
            delete this.persisterListeners[key];
        }
    }

    public static valueOf(querier: Querier): TimerAccessor {
        var result: TimerAccessor = new TimerAccessor();
        result.querier = querier;
        return result;
    }

    private addSaveQueue(name: EntityName, entity: Entity): void {
        var key: string = name + "";
        var id: string = entity.getId();
        if (this.saveQueue[key] == null) {
            this.saveQueue[key] = {};
        }
        this.saveQueue[key][id] = entity;
    }

    private addDelQueue(name: EntityName, entity: Entity): void {
        var key: string = name + "";
        var id: string = entity.getId();
        if (this.saveQueue[key] == null) {
            return;
        }
        delete this.saveQueue[key][id];
    }
}
Querier.ts
/** 查询器 */
interface Querier {
    /** 保存数据 */
    save(name: EntityName, entity: Entity): void;
    /** 查询指定数据 */
    findOne(name: EntityName, id: any): Entity;
    /** 查询所有数据 */
    findAll(name: EntityName): Array<Entity>;
    /** 查询指定数据 */
    find(name: EntityName, ...queryParams: Array<any>): Array<Entity>;
    /** 删除数据 */
    remove(name: EntityName, id: any): void;
}

/** MySQL查询器 */
class MysqlQuerier implements Querier {
    private static query_all_tpl: string = "SELECT * FROM {name}";
    private connection: MySqlIConnection;

    public save(name: EntityName, entity: Entity): void {
        // 保存逻辑
    }

    public findOne(name: EntityName, id: any): Entity {
        return {}; // 模拟返回值
    }

    public findAll(name: EntityName): Array<Entity> {
        var result: Array<Entity> = [];
        var sql: string = MysqlQuerier.query_all_tpl;
        this.connection.query(sql, function(err, rows, fields) {
            if (err) throw err;
            for (var i in rows) {
                // 处理每一行数据
            }
        });
        return result;
    }

    public find(name: EntityName, ...queryParams: Array<any>): Array<Entity> {
        return [];
    }

    public remove(name: EntityName, id: any): void {
        // 删除逻辑
    }
}

declare var module: any;
module.exports = MysqlQuerier;
RamCacheService.ts
/** 高速缓存服务 */
class RamCacheService {
    private entityMetadata: EntityMetadata;
    private accessor: Accessor;
    private querier: Querier;
    private cacheData: { [id: string]: Entity; } = {};

    public valueOf(accessor: Accessor, querier: Querier, entityMetadata: EntityMetadata): RamCacheService {
        var result: RamCacheService = new RamCacheService();
        result.accessor = accessor;
        result.querier = querier;
        result.entityMetadata = entityMetadata;
        result.initCacheData();
        return result;
    }

    private addCacheData(entity: Entity) {
        var id: string = entity.getId();
        this.cacheData[id] = entity;
    }

    private getCacheData(id: any): Entity {
        return this.cacheData[id];
    }

    private removeCacheData(entity: Entity) {
        var id: string = entity.getId();
        delete this.cacheData[id];
    }

    private initCacheData(): void {
        var name = this.entityMetadata.entityName;
        var cacheConfig: CacheConfig = this.entityMetadata.cacheConfig;
        if (cacheConfig.initCacheConfig != null) {
            var initCacheConfig: InitCacheConfig = cacheConfig.initCacheConfig;
            var datas: Array<Entity>;
            switch (initCacheConfig.initType) {
                case InitCacheType.ALL:
                    datas = this.querier.findAll(name);
                    break;
                case InitCacheType.QUERY:
                    datas = this.querier.find(name, initCacheConfig.queryValue);
                    break;
                default:
                    return;
            }
            for (var entity of datas) {
                this.addCacheData(entity);
            }
        }
    }

    public loadOrCreate(id: any, callback: (id: any) => Entity): Entity {
        var resultEntity: Entity = this.getCacheData(id);
        if (resultEntity == null) {
            var name = this.entityMetadata.entityName;
            resultEntity = this.accessor.load(name, id);
        }

        if (resultEntity == null) {
            resultEntity = callback(id);
            this.save(resultEntity);
        }
        return resultEntity;
    }

    public save(entity: Entity): void {
        var name = this.entityMetadata.entityName;
        this.accessor.save(name, entity);
        this.addCacheData(entity);
    }

    public update(entity: Entity): void {
        this.save(entity);
    }

    public remove(entity: Entity): void {
        var name = this.entityMetadata.entityName;
        this.accessor.remove(name, entity);
        this.removeCacheData(entity);
    }

    public getEntityMetadata(): EntityMetadata {
        return this.entityMetadata;
    }
}

declare var module: any;
module.exports = RamCacheService;

测试代码

const mysql = require('mysql');
const entity = require('./Entity');
const querier = require('./Querier');
const accessor = require('./Accessor');
const ramCacheService = require('./RamCacheService');

const connection = mysql.createConnection({
    host: 'localhost',
    port: 8585,
    database: 'test',
    user: 'root',
    password: '1212'
});
connection.connect();

const mysqlQuerier = querier.valueOf(connection);
const timerAccessor = accessor.valueOf(mysqlQuerier);

mysqlQuerier.findAll(entity.EntityName.test, function (res) {
    // console.log(res);
});

_find();

function _find() {
    const startTime = new Date().getTime();
    timerAccessor.load(entity.EntityName.test, 1, function (res) {
        return { id: 1 };
    }, function (res) {
        const endTime = new Date().getTime();
        console.log(`find time : ${endTime - startTime}`);
        console.log(res);

        cache_find();
    });
}

function cache_find() {
    const startTime = new Date().getTime();
    timerAccessor.load(entity.EntityName.test, 1, function (res) {
        return { id: 1 };
    }, function (res) {
        const endTime = new Date().getTime();
        console.log(`find cache time : ${endTime - startTime}`);
        console.log(res);
    });
}

运行结果

find time : 9
{ id: 1, body: '2121' }
find cache time : 1
{ id: 1, body: '2121' }

以上代码展示了如何使用 Rawcache 来实现高速缓存服务,并通过 AccessorQuerier 接口来处理数据的持久化和查询操作。


顶一个

马上要完成了,欢迎各位给点意见

TS不错,赞一个

dart也不错,不过都代替不了javascript.

跟as 挺像的……

as已经快不存在了。

dart,type script正是因为ms和google认识到js的不足。

项目已共享,欢迎给意见

不管你用什么语言将string转换成int,是不是都应该先验证下是否可以转换? 无论是自己写个正则表达式进行判断,还是用jquery插件进行判断,都比直接转换来得合理些。

根据提供的内容,“Nodejs rawcache 高速缓存”主要介绍了如何使用 TypeScript 来实现一个基于内存的高速缓存系统。这个系统通过 RamCacheService 类来管理缓存,并通过 Accessor 接口来处理数据的持久化操作。以下是基于提供的代码片段的一个简化示例,展示如何使用这个高速缓存系统。

示例代码

首先定义基本的 Entity 类:

class Entity {
    id: number;
    body: string;

    constructor(id: number, body: string) {
        this.id = id;
        this.body = body;
    }

    getId(): number {
        return this.id;
    }
}

接下来是 EntityMetadata 类,这里只是简单定义了实体的名称和缓存配置:

class EntityMetadata {
    entityName: string;
    cacheConfig: any;

    constructor(entityName: string, cacheConfig: any) {
        this.entityName = entityName;
        this.cacheConfig = cacheConfig;
    }
}

CacheConfigInitCacheType 等类在这里省略,假设已经定义好了。

然后是 Accessor 接口的实现,这里以 TimerAccessor 为例:

class TimerAccessor implements Accessor {
    // 数据查询器
    private querier: Querier;

    // 保存队列
    private saveQueue: { [id: string]: Entity } = {};
    // 删除队列
    private removeQueue: { [id: string]: Entity } = {};

    public save(name: string, entity: Entity): void {
        this.saveQueue[entity.getId()] = entity;
    }

    public update(name: string, entity: Entity): void {
        this.saveQueue[entity.getId()] = entity;
    }

    public load(name: string, id: number): Entity {
        return this.saveQueue[id] || null;
    }

    public remove(name: string, entity: Entity): void {
        delete this.saveQueue[entity.getId()];
    }

    public persister(name: string): void {
        // 这里可以添加持久化逻辑,例如将 saveQueue 中的数据写入数据库
    }
}

最后是 RamCacheService 的实现:

class RamCacheService {
    private entityMetadata: EntityMetadata;
    private accessor: Accessor;
    private cacheData: { [id: string]: Entity } = {};

    public valueOf(accessor: Accessor, querier: Querier, entityMetadata: EntityMetadata): RamCacheService {
        this.accessor = accessor;
        this.entityMetadata = entityMetadata;
        return this;
    }

    public loadOrCreate(id: number, callback: (id: number) => Entity): Entity {
        let resultEntity = this.cacheData[id];
        if (!resultEntity) {
            resultEntity = this.accessor.load(this.entityMetadata.entityName, id);
            if (!resultEntity) {
                resultEntity = callback(id);
                this.save(resultEntity);
            }
        }
        return resultEntity;
    }

    public save(entity: Entity): void {
        this.accessor.save(this.entityMetadata.entityName, entity);
        this.cacheData[entity.getId()] = entity;
    }

    public update(entity: Entity): void {
        this.save(entity);
    }

    public remove(entity: Entity): void {
        this.accessor.remove(this.entityMetadata.entityName, entity);
        delete this.cacheData[entity.getId()];
    }

    public getEntityMetadata(): EntityMetadata {
        return this.entityMetadata;
    }
}

通过上述代码,你可以创建一个基于内存的高速缓存系统,它能够有效地缓存数据库中的数据,并提供快速的读取操作。

回到顶部