解决缓存问题无Redis可行方案(不用redis怎么做缓存)

  Web应用中,最常用的缓存方案就是使用Redis,但是有时候Redis可能不太合适,例如部署成本太高、代码写起来很麻烦等等。对于这些问题,还有另外几种方式可以解决缓存问题。

  两级缓存是一种常用的解决缓存问题的方式,其两个层次分别是本地缓存和远程缓存,针对定时任务可以使用该方案。一级缓存可以为本地散列,二级缓存可以为远程数据库,引擎可以按照一致性原则进行触发,有利于性能提升,而散列的优势更显著,因此可以采用散列的方式存储本地数据,具体代码如下:

// 一级缓存:本地散列
var hashTable = {};

// 二级缓存:远程数据库
var remoteDB = {};
// 判断一级缓存里是否存在,如果存在则从缓存中获取
function get(key) {
if (hashTable[key] !== undefined) {
return hashTable[key];
}
// 一级缓存不存在,则从二级缓存中获取
else {
var val = remoteDB.get(key);
if (val !== undefined) {
// 二级缓存存在,则将值保存到一级缓存里
hashTable[key] = val;
}
return val;
}
}

  另一种解决缓存问题的方案是LRU( Least Recently Used)策略,即最近最少使用策略,在处理缓存淘汰时,先去掉最近最少使用的。LRU策略也可以称为近期最少使用( RecentlyLeast Used)算法,也是一种最常用的缓存淘汰算法。具体实现也很简单,可以使用双向链表来维护缓存,分别按照顺序存放最近使用的元素到头部,最久使用的元素到尾部,当有缓存放入,则会放在头部,当缓存放满,则替换掉尾部的数据,具体实现如下:

// 使用双向链表维护缓存
class DLinkedNode {
constructor(key = null, value = null) {
this.key = key;
this.value = value;
this.pre = null;
this.next = null;
}
}
class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.map = {};
this.head = new DLinkedNode();
this.tl = new DLinkedNode();
this.head.next = this.tl;
this.tl.pre = this.head;
}

get(key) {
let node = this.map[key];
// 不存在
if (!node) {
return -1;
}
// 把节点放在头部
this._moveToHead(node);
return node.value;
}

put(key, value) {
let node = this.map[key];
// 添加
if (!node) {
let newNode = new DLinkedNode(key, value);
this.map[key] = newNode;
this._addToHead(newNode);
this.capacity--;
// 删除最后一个
if (this.capacity
this._removeTl();
}
}
// 更新
else {
node.value = value;
this._moveToHead(node);
}
}

_removeTl() {
let tlNode = this.tl.pre;
this._removeNode(tlNode);
delete this.map[tlNode.key];
this.capacity++;
}

_removeNode(node) {
let preNode = node.pre;
let nextNode = node.next;
preNode.next = nextNode;
nextNode.pre = preNode;
}

_addToHead(node) {
let preHead = this.head;
let afterHead = preHead.next;
preHead.next = node;
afterHead.pre = node;
node.next = afterHead;
node.pre = preHead;
}

_moveToHead(node) {
this._removeNode(node);
this._addToHead(node);
}
}

  以上两种方法无需使用Redis就可以实现缓存,能够解决部署成本高等问题,因此在不能使用Redis的情况下,也可以考虑采用以上方案。


数据运维技术 » 解决缓存问题无Redis可行方案(不用redis怎么做缓存)