喻轩Blog - 其他缓存服务
type: channel
link: https://blog.yuxuan.io/categories/%E5%85%B6%E4%BB%96%E7%BC%93%E5%AD%98%E6%9C%8D%E5%8A%A1
description: 其他缓存服务
items: Aerospike
items: Tair
items: EVCache
items: Guava Cache
items: 缓存回顾

Aerospike
type: item
date: 2020-10-09T14:25:09+08:00
description: Aerospike介绍Aerospike（简称AS）是一个分布式，可扩展的键值存储的NoSQL数据库。T级别大数据高并发的结构化数据存储读写操作达微妙级，99%的响应可在1毫秒内实现采用混合架构，索引存储在内存中，而数据可存储在机械硬盘(HDD)或固态硬盘(SSD) 上（也可存储在内存）AS内部在访问SSD屏蔽了文件系统层级，直接访问地址，保证了数据的读取速度。AS同时支持二级索引与Client聚合，支持简单的sql操作（aql），相比于其他nosql数据库，有一定优势。Aerospike应用场景-广告行业Aerospike作为一个大容量的NoSql解决方案，并未在国内厂中广泛商使用。它适合对容量要求比较大，QPS相对低一些的场景，目前主要集中于互联网广告行业使用（国外）个性化推荐广告应用个性化推荐厂告是建立在了和掌握消费者独特的偏好和习性的基础之上，对消费者的购买需求做出准确的预测或引导，在合适的位置、合适的时间，以合适的形式向消费者呈现与其需求高度吻合的广告，以此来促进用户的消费行为。用户行为日志收集系统收集日志之后推送到ETL做数据的清洗和转换，把ETL过后的数据发送到推荐引擎计算每个消费者的推荐结果，其中推荐逻辑包括规则和算法两部分具体的规则有用户最近浏览、加入购物车、加入收藏等算法则包括商品相似性、用户相似性、文本相似性、图片相似性等算法。把推荐引擎的结果存入Aerospike集群中，并提供给广告投放引擎实时获取实时竞价广告应用当用户浏览一个加入SSP（供应方平台）的站点时，SSP会把此次请求发送到AD EXCHANGE（广告交易平台），然后ADX会把这次请求发送给多家DSP，DSP（需求方平台）根据自身的DMP（数据管理平台），通过对次用户的了解程度进行竞价，最终竞价胜出的DSP获得展现广告的机会。DSP竞价（RTB：实时竞价）胜出的关键是DMP能够根据用户的历史浏览等数据分析和定位用户属性，其中实时竞价广告中非常重要的一个环节就是UserProfile（用户画像）。分别通过HDFS和HBASE对日志进行离线和实时的分析，然后把用户画像的标签(tag : 程序猿、宅男...)结果存入高性能的Nosql数据库Aerospike中，同时把数据备份到异地数据中心。前端广告投放请求通过决策引擎（投放引擎）向用户画像数据库中读取相应的用户画像数据，然后根据竞价算法出价进行竞价。竞价成功之后就可以展现广告了。而在竞价成功之后，具体给用户展现什么样的广告，就是有上面说的个性化推荐广告来完成的。Aerospike与Redis对比Aerospike是NoSQL的数据存储，Redis是缓存Aerospike是多线程的，而 Redis 是单线程的Redis 需要开发人员自己管理分片并提供分片算法用于在各分片之间平衡数据；client： hash 一致性hashcodis ：代理处理shardingRedisCluster： hash槽而 AerospikeDB 可以自动处理相当于分片的工作；在 Redis 中，为了增加吞吐量，需要增加 Redis 分片的数量，并重构分片算法及重新平衡数据，这通常需要停机；而在 AerospikeDB 中，可以动态增加数据卷和吞吐量，无需停机，并且 AerospikeDB 可以自动平衡数据和流量；在 Redis 中，如果需要复制及故障转移功能，则需要开发人员自己在应用程序层同步数据；而在 AerospikeDB 中，只需设置复制因子，然后由 AerospikeDB 完成同步复制操作，保持即时一致性；而且 AerospikeDB 可以透明地完成故障转移；Redis是在内存中运行的 ，AerospikeDB在内存中存储索引，在HDD、SSD中保存数据，也可以在内存中Aerospike架构Aerospike分为三个层次：Client层：对Aerospike Server中的数据进行访问。包括CRUD、批量操作和基于二级索引的查询是一个“智能”客户端，支持C/C++、Java、GoLang、Python、C#、Php、Ruby、JavaScript等绝大部分主流语言。追踪节点感知数据存储位置，当节点启动或停止时立即感知集群配置变化。具有高效性、稳定性和内部的连接池Distribution层：负责管理集群内部数据的平衡分布、备份、容错和不同集群之间的数据同步。主要包含三个模块：Cluster Management Module用于追踪集群节点。关键算法是确定哪些节点是集群的一部分的Paxos-like一致投票过程。Aerospike实现专门的心跳检测（主动与被动），用于监控节点间的连通性。Data Migration Module当有节点添加或移除时，该模块保证数据的重新分布，按照系统配置的复制因子确保每个数据块跨…

Tair
type: item
date: 2020-10-09T11:42:54+08:00
description: Tair介绍Tair简介Tair(Taobao Pair)是淘宝开发的分布式Key-Value存储引擎，服务器端自动负载均衡，分为持久化和非持久化两种方式存储非持久化：分布式缓存使用 Memcached（mdb）、Redis（rdb）持久化：SQL-DB使用FireBird（fdb）NoSQL-DB：使用Kyoto Cabinet（kdb）、LevelDB（ldb）Tair采用可插拔存储引擎设计，以上这些存储引擎可以很方便的替换，还可以引入新的存储引擎比如：MySQL使用场景分布式缓存大多数使用场景：大访问少量临时数据的存储（kb左右）用于缓存，降低对后端数据库的访问压力session场景：高速访问某些数据结构的应用和计算（rdb）数据源存储快速读取数据（fdb）持续大数据量的存入读取（ldb），交易快照高频度的更新读取（ldb），库存Tair整体架构分析一个Tair集群主要包括client、Config server和Dataserver 三个不同的应用。Client在初始化时，从Config server处获取数据的分布信息，根据分布信息和相应的Data server交互完成用户的请求。Config Server通过和Data Server的心跳（HeartBeat）维护集群中可用的节点，并根据可用的节点，构建数据的在集群中的分布信息Data server负责数据的存储，并按照Config server的指示完成数据的复制和迁移工作。Config ServerConfig Server是单点，采用一主一备的方式保证可靠性。管理所有的data server，维护data server的状态信息，用户配置的桶数量、副本数、机房信息和数据分布的对照表协调数据迁移、管理进度，将数据迁移到负载较小的节点上Client和ConfigServer的交互主要是为了获取数据分布的对照表，当client获取到对照表后，会cache这张表，然后通过查这张表决定数据存储的节点，所以不需要和configserver交互，这使得Tair对外的服务不依赖configserver，所以它不是传统意义上的中心节点Config server维护的对照表有版本概念，由于集群变动或管理触发，构建新的对照表后，对照表的版本号递增，并通过Data server的心跳，将新表同步给数据节点。客户端和Data server交互时，Dataserver每次都把自己缓存的对照表版本号放入response结构中，返回给客户端，客户端将Data server的对照表版本号和自己缓存的对照表版本号比较，如果不相同，会主动和Config server通信，请求新的对照表。Tair的Configserver使客户端使用时候，不需要配置数据节点列表，也不需要处理节点的的状态变化，这使得Tair对最终用户来说使用和配置都很简单。Data ServerData server负责数据的物理存储，并根据Configserver构建的对照表完成数据的复制和迁移工作。Data server具备抽象的存储引擎层，可以很方便地添加新存储引擎。Data server还有一个插件容器，可以动态地加载/卸载插件。Tair的存储引擎有一个抽象层，只要满足存储引擎需要的接口，便可以很方便地替换Tair底层的存储引擎。比如你可以很方便地将bdb、tc甚至MySQL作为Tair的存储引擎，而同时使用Tair的分布方式、同步等特性。Tair默认包含两个存储引擎：mdb和fdb。mdb是一个高效的缓存存储引擎，它有着和memcached类似的内存管理方式。mdb支持使用share memory（tmpfs），这使得我们在重启Tair数据节点的进程时不会导致数据的丢失，从而使升级对应用来说更平滑，不会导致命中率的较大波动。fdb是一个简单高效的持久化存储引擎，使用树的方式根据数据key的hash值索引数据，加快查找速度。索引文件和数据文件分离，尽量保持索引文件在内存中，以便减小IO开销。使用空闲空间池管理被删除的空间。Tair的安装与使用环境准备Gityum install git yum update -y nss curl libcurlsvnyum install subversionLibtoolyum install libtoolboost-develyum install boost-develzlibyum install zlib-develC++yum install gcc-c++项目源码下载和编译tbsys库和tbnet库下载（tair底层依赖tbsys库和tbnet库）#git源码下载 git clone https://github.com/kayaklee/tb-common-util.gi…

EVCache
type: item
date: 2020-10-09T10:58:17+08:00
description: EVCache介绍EVCache是一个开源、快速的分布式缓存，是基于Memcached的内存存储和Spymemcached客户端实现的，是Netflix（网飞）公司开发的E：Ephemeral：数据存储是短暂的，有自身的存活时间V：Volatile：数据可以在任何时候消失Cache：内存级键值对存储Rend服务：是一个代理服务，用GO语言编写，能够高性能的处理并发。Memcached：基于内存的键值对缓存服务器Mnemonic：基于硬盘（SSD）的嵌入式键值对存储服务器，封装了RocksDB(是一种SSD的技术)EVCache集群在峰值每秒可以处理200kb的请求，Netflix生产系统中部署的EVCache经常要处理超过每秒3000万个请求，存储数十亿个对象，跨数千台memcached服务器。整个EVCache集群每天处理近2万亿个请求。EVCache集群响应平均延时大约是1-5毫秒，最多不会超过20毫秒。EVCache集群的缓存命中率在99%左右。EVCache的应用典型用例Netflix用来构建超大容量、高性能、低延时、跨区域的全球可用的缓存数据层EVCache典型地适合对强一致性没有必须要求的场合典型用例：Netflix向用户推荐用户感兴趣的电影典型部署EVCache 是线性扩展的，可以在一分钟之内完成扩容，在几分钟之内完成负载均衡和缓存预热。单节点部署集群启动时，EVCache向服务注册中心（Zookeeper、Eureka）注册各个实例在web应用启动时，通过EVCache的客户端(EVCache Client)查询命名服务中的EVCache服务器列表，并建立连接。web应用通过EVCache的客户端操作数据，客户端通过key使用一致性hash算法，将数据分片到集群上。多可用区部署EVCache的跨可用区复制：EVCache客户端库包发送SET到缓存系统的本地地区的一个实例服务器中。EVCache客户端库包同时也将写入元数据(包括key，但是不包括要缓存的数据本身)到复制消息队列(Kafka)本地区的“复制转播”的服务将会从这个消息队列中读取消息。转播服务会从本地缓存中抓取符合key的数据转播会发送一个SET请求到远地区的“复制代理”服务。在远地区，复制代理服务会接受到请求，然后执行一个SET到它的本地缓存，完成复制。在接受地区的本地应用当通过GET操作以后会在本地缓存看到这个已经更新的数据值。EVCache的安装与使用由于Netflix没有开源EVCache的服务器部分，这里采用Memcached作为服务器。安装Memcached#安装libevent库 yum install libevent libevent-devel gcc-c++ #下载最新的memcached wget http://memcached.org/latest #解压 tar -zxvf latest #进入目录 cd memcached-1.6.6 #配置 ./configure --prefix=/usr/memcached #编译 make #安装 make install #启动 memcached -d -m 1000 -u root -l 192.168.127.131 -p 11211 -c 256 -P /tmp/memcached.pid-d 选项是启动一个守护进程-m 是分配给Memcache使用的内存数量，单位是MB，我这里是10MB-u 是运行Memcache的用户，我这里是root-l 是监听的服务器IP地址，我这里指定了服务器的IP地址192.168.127.131-p 是设置Memcache监听的端口，我这里设置了11211（默认），最好是1024以上的端口-c 选项是最大运行的并发连接数，默认是1024，我这里设置了256，按照你服务器的负载量来设定-P 是设置保存Memcache的pid文件，我这里是保存在 /tmp/memcached.pid使用EVCache Clientpom<dependency> <groupId>com.netflix.evcache</groupId> <artifactId>evcache-client</artifactId> <version>4.139.0</version> </dependency> <dependency> <groupId>net.spy</groupId> <artifactId>spymemcached</artifactId> <version>2.12.3</version> </dependency> <dependency> <groupId>com.netflix.eureka</groupId> <artifactId>eur…

Guava Cache
type: item
date: 2020-10-09T10:35:16+08:00
description: Guava Cache介绍JVM缓存JVM 缓存，是堆缓存。其实就是创建一些全局容器，比如List、Set、Map等，这些容器用来做数据存储。这样做的问题：不能按照一定的规则淘汰数据，如 LRU，LFU，FIFO 等。没有清除数据时的回调通知并发处理能力差，针对并发可以使用CurrentHashMap，但缓存的其他功能需要自行实现缓存过期处理，缓存数据加载刷新等都需要手工实现Guava CacheGuava是Google提供的一套Java工具包，而Guava Cache是一套非常完善的本地缓存机制（JVM缓存）。Guava cache的设计来源于CurrentHashMap，可以按照多种策略来清理存储在其中的缓存值且保持很高的并发读写性能。Guava Cache应用场景本地缓存的应用场景：对性能有非常高的要求不经常变化占用内存不大有访问整个集合的需求数据允许不时时一致guava cache高并发，不需要持久化currentHashMap高并发Ehcached持久化 二级缓存Guava Cache 的优势：缓存过期和淘汰机制在GuavaCache中可以设置Key的过期时间，包括访问过期和创建过期GuavaCache在缓存容量达到指定大小时，采用LRU的方式，将不常使用的键值从Cache中删除并发处理能力GuavaCache类似CurrentHashMap，是线程安全的。提供了设置并发级别的api，使得缓存支持并发的写入和读取采用分离锁机制，分离锁能够减小锁力度，提升并发能力，分离锁是分拆锁定，把一个集合看分成若干partition，每个partiton一把锁。（同ConcurrentHashMap）就是分了16个区域，这16个区域之间是可以并发的。GuavaCache采用Segment做分区。更新锁定一般情况下，在缓存中查询某个key，如果不存在，则查源数据，并回填缓存。（Cache Aside Pattern）在高并发下会出现，多次查源并重复回填缓存，可能会造成源的宕机（DB），性能下降GuavaCache可以在CacheLoader的load方法中加以控制，对同一个key，只让一个请求去读源并回填缓存，其他请求阻塞等待。集成数据源一般我们在业务中操作缓存，都会操作缓存和数据源两部分而GuavaCache的get可以集成数据源，在从缓存中读取不到时可以从数据源中读取数据并回填缓存监控缓存加载/命中情况统计Guava Cache创建方式GuavaCache有两种创建方式：CacheLoader和Callable callbackpublic class GuavaDemo { public static void main(String args[]) throws Exception { LoadingCache<String,Object> cache = CacheBuilder.newBuilder() // 最大3个 .maximumSize(3) //Cache中存储的对象,写入3秒后过期 .expireAfterWrite(3,TimeUnit.SECONDS) //记录命中率 .recordStats() //失效通知 .removalListener(new RemovalListener<Object, Object>() { public void onRemoval(RemovalNotification<Object, Object> notification){ System.out.println(notification.getKey()+":"+notification.getCause()); } } .build( new CacheLoader<String, Object>() { @Override public String load(String s) throws Exception { return Constants.hm.get(s); } } ); //初始化cache initCache(cache); System.out.println(cache.size()); displayCache(cache); System.out.println("============================="); Thread.sleep(1000); System.out.println(cache.getIfPresent("1")); Thread.sleep(2500); System.out.println("============================="); displayCache(cache); } public static Objec…

缓存回顾
type: item
date: 2020-10-09T09:43:19+08:00
description: 使用场景：互联网，数据越来越多，用户越来越多，并发量、吞吐量越来越大使用数据库存储，分库分表，也不能满足要求，使用缓存，减轻数据库的压力临时存储的数据其他的场景：Session分离、分布式锁缓存（服务器端）：本地缓存（local cache）CurrentHashMap、Ehcache、Guava Cache缓存在应用服务器，全局变量，JVM缓存优势：和应用程序在同一进程，访问快，没有网络开销，一般不会崩缺点：容量小，每个JVM有一份，有数据冗余分布式缓存Redis、Memcached、Tair（阿里、美团）、EVCache（AWS）、Aerospike优势：空间优势、在应用中共享（session共享）、高可用（主从）、高扩展（分区）、集群缺点：资源、网络开销、数据一致性（AP）前面已经详解了Redis，接下来讲其他的缓存GuavaCache、Tair、EVCache、Aerospike比较 GuavaCacheTairEVCacheAerospike类别本地缓存（JVM缓存）分布式缓存分布式缓存分布式NoSQL数据库应用高并发本地缓存阿里、美团Netflix、AWS互联网广告行业（国外）性能高较高很高较高持久化无有有有集群无有有有