开源项目ets_cache分析

1 背景

  当在程序中,有大量的数据需要读写,数据库的响应会延迟,甚至阻塞。缓存可以缓解对数据库访问的压力,而且在内存中数据的读写要比读写硬盘上的数据快。

2 目的

  ets_cache是用erlang实现的简单的缓存应用,它的结构简单,但功能强大支持百万级的数据量。其主要是用来存储一些公共访问的数据,这些数据存放在ets表中,借助ets表的高性能对数据进行操作。

3 结构

  3.1 源码目录

              下图是ets_cache的源码目录截图:

                                开源项目ets_cache分析_第1张图片

              include:主要是一些宏定义和引入的一些包。其中定义了默认缓存ets表(ets_cache_data)

              test:主要是测试代码

              src:是源代码文件

                      ets_cache_app.erl                   应用程序启动文件

                      ets_cache_sup.erl                   ets_cache的supervisor行为

                      ets_cache.erl                          ets_cache的对外接口

                      ets_cache_manager_sup.erl    ets_cache_manager的supervisor行为

                      ets_cache_manager.erl           ets_cache的管理进程,是gen_server行为,维护着每个ets缓存表

  3.2 监控树结构

            下图是ets_cache的监控结构:

      

             从图中我们当我们启动ets_cache应用并创建缓存表,创建的缓存表都被ets_cache_manager_sup的子节点,并对其进行维护。

4 核心

  ets_cache虽然简单,但是有两点值得借鉴:

       1.每个ets表专属一个进程。当我们存储新的一类数据时,就可以创建新的进程,创建ets表,单进程维护ets表,保证了ets表的独立性。

       2.ets表会定时清理冷数据。ets表的数据应该是访问频率较高的数据,每次访问玩数据都会更新数据的过期时间,而且每个一段时间进程就会对ets表进行一次清理,清理过时的数据,避免ets表的数据过于臃肿。

源码如下:

 1  handle_info(cleanup, #state{
 2 
 3                          table = Table,
 4 
 5                          clean_interval = CleanInterval
 6 
 7                         } = State) ->
 8 
 9      Now = ets_cache:unixtime(),
10 
11      %% error_logger:info_msg("cleanup now ~p~n", [Now]),
12 
13      MS = ets:fun2ms(
14 
15             fun({_, _, Timeout}) when is_integer(Timeout)->
16 
17                     Timeout =< Now
18 
19             end),
20 
21      ets:select_delete(Table, MS),
22 
23      erlang:send_after(CleanInterval, self(), cleanup),
24 
25      {noreply, State};

5 总结

  ets_cache虽然设计简单,但是实用。能支持不同类型的数据,创建不同的ets表,而且读写效率高,实用与大量数据的缓存。并可以稍加改动就可以作为数据库和程序之间的缓存。但是,对于数据一致性要求较高的数据要慎用。当所有数据访问频率不高时,清除掉冷数据会产生ets空表。

 

ets_cache源码地址:https://github.com/roowe/ets_cache

 

优秀的代码是艺术品,它需要精雕细琢!

 

你可能感兴趣的:(cache)