NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:https://github.com/NewLifeX/X (求star, 770 )
单对象缓存
前文提到了以sql为key的数据层缓存,以及整表缓存的实体列表缓存,各自有其优缺点,适用于不同场合。
当单表数据较大(10万 )时,两者就无能为力了。天空一道巨响,对象字典缓存隆重登场!
对象字典缓存:以主键为key,缓存实体对象,以满足应用层的高频单点查询需求!
例程跑起来:
先给学生表加了100万行,再随机生成1024个编号,然后查询1000万次。速度200万qps,命中率99.99%。
缓存本质
Student.FindByID内使用了单对象缓存:Meta.SingleCacheid;
单对象缓存本质就是并行字典,因此使用方式上只需要直接索引器查找即可。
在Meta.SingleCache内查找id时,如果已存在,则直接返回,否则执行委托Student.FindByKey查找对象后缓存起来。
非XCode用户,也可以根据该思想设计自己的缓存。
单对象缓存也有过期时间,默认10秒,过期后异步更新(老规矩,为了性能)。
单对象缓存还会根据LRU定期清理缓存,此时采用最后访问时间而不是过期时间。
对象缓存还有最大缓存数限制,默认10000个,超过时删除最久未访问缓存数据。
因此,单对象缓存特别适用于单行特点很突出且修改不多的数据,如用户表、产品表等。
即使目标表有千万级数据,单对象字典缓存仍然可以轻松的取敌首级!^_^
从键查询
前面实例展示了根据ID查找缓存对象,实际应用场景,还可能会根据名称进行查找,总不能另外搞一个对象缓存吧?
来自深圳的海洋饼干,很有创意的解决了这个问题,发明了从键缓存!
如上,Meta.SingleCache.GetItemWithSlaveKey(name) 实现了根据 name 查询用户。
在此之前,需要手工配置查询方法,因为XCode已经无法猜测得知。
使用从键缓存后,等于有两个入口(FindKey/FindSlaveKey)查询数据库,得到一个实体对象后,分别加入主键字典和从键字典,用于两个维度索引查询。
因此,从键缓存需要配置根据从键查数据库的方法FindSlaveKeyMethod,同时还需要配置实体对象获取从键值的方法GetSlaveKey,因为主键查库后加入从键缓存时,需要从对象内得到从键值。
过期策略
所有缓存都必须有过期策略。单对象字典缓存的过期策略有以下:
- 初始化。首次访问缓存时,无需阻塞,并行查询。
- 定时过期。缓存过期后,开异步线程更新并同时返回旧数据,确保应用层性能。设置文件的 SingleCacheExpire, 默认10秒
- 添删改过期。对实体类的添删改操作完成后,都会直接修改缓存对应项。
显然,初始化加载以后,将来访问的永远是定时更新的缓存数据,应用层可以得到非常好的性能!
由于缓存的添删改过期跟实体操作绑定在一起,因此,越过实体类直接DAL执行更新操作,或者其它服务器修改数据,此时无法影响实体缓存,导致数据更新不及时。
早期版本XCode缓存默认过期时间60秒,随着数据库性能提升,默认值修改为10秒,可根据实际场景设置。
系列教程
NewLife.XCode教程系列2019版
- 增删改查入门。快速展现用法,代码配置连接字符串
- 数据模型文件。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
- 实体类详解。数据类业务类,泛型基类,接口
- 功能设置。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
- 反向工程。自动建立数据库数据表
- 数据初始化。InitData写入初始化数据
- 高级增删改。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
- 脏数据。如何产生,怎么利用
- 增量累加。高并发统计
- 事务处理。单表和多表,不同连接,多种写法
- 扩展属性。多表关联,Map映射
- 高级查询。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
- 数据层缓存。Sql缓存,更新机制
- 实体缓存。全表整理缓存,更新机制
- 对象缓存。字典缓存,适用用户等数据较多场景。
- 百亿级性能。字段精炼,索引完备,合理查询,充分利用缓存
- 实体工厂。元数据,通用处理程序
- 角色权限。Membership
- 导入导出。Xml,Json,二进制,网络或文件
- 分表分库。常见拆分逻辑
- 高级统计。聚合统计,分组统计
- 批量写入。批量插入,批量Upsert,异步保存
- 实体队列。写入级缓存,提升性能。
- 备份同步。备份数据,恢复数据,同步数据
- 数据服务。提供RPC接口服务,远程执行查询,例如SQLite网络版
- 大数据分析。ETL抽取,调度计算处理,结果持久化