详解nodejs如何实现查询缓存

 更新时间:2023年12月06日 13:59:22   作者:vin_zheng  
对于频繁查询、数据稳定性高、读取代价高的场景,查询缓存可以发挥重要的作用,提高系统的性能和用户体验,下面我们就来学习一下nodejs是如何实现查询缓存的

我相信你肯定在不同场景下吐槽过某个搜索响应慢,列表展示迟,详情页白屏久等问题。对于频繁查询、数据稳定性高、读取代价高的场景,查询缓存可以发挥重要的作用,提高系统的性能和用户体验。

实现缓存的关键

在实现查询缓存时,以下是一些需要考虑的关键方面:

1. 缓存策略

需要选择合适的缓存策略,例如LRU(最近最少使用)、LFU(最不经常使用)等。缓存策略决定了缓存中的数据何时被淘汰或更新。以下是一个示例代码,展示了如何使用 lru-cache 库实现 LRU 缓存策略:

const LRU = require('lru-cache');

// 创建一个 LRU 缓存实例
const cache = new LRU({
  max: 100, // 最大缓存条目数
  maxAge: 60000, // 条目在缓存中的最长存活时间(毫秒)
});

function getDataFromCache(key) {
  const data = cache.get(key);
  if (data) {
    console.log('Fetching data from cache for key:', key);
    return data;
  }
  return null;
}

function setDataToCache(key, data) {
  console.log('Setting data to cache for key:', key);
  cache.set(key, data);
}

2. 缓存失效

当后端数据发生变化时,需要及时使缓存失效,以避免返回过期或不一致的数据。可以根据业务需求设置缓存的失效时间(例如根据数据更新频率),或者在数据发生变化时手动使缓存失效。以下是一个示例代码,展示了如何手动使缓存失效:

function updateDataInDatabase(key, newData) {
  // 更新数据库中的数据
  // ...

  // 使缓存失效
  cache.del(key);
}

3. 并发访问

并发访问可能导致缓存的竞态条件和不一致性。可以使用互斥锁或其他并发控制机制来保证对缓存的访问的原子性和一致性。以下是一个示例代码,展示了如何使用 async-mutex 库实现互斥锁:

const { Mutex } = require('async-mutex');
const mutex = new Mutex();

async function getDataWithCache(key) {
  const release = await mutex.acquire();
  try {
    let data = getDataFromCache(key);
    if (!data) {
      // 从数据库获取数据
      data = fetchFromDatabase(key);
      // 将数据设置到缓存
      setDataToCache(key, data);
    }
    return data;
  } finally {
    release();
  }
}

4. 缓存命中率和效果评估

需要监控和评估缓存的命中率和效果,以便调优和改进缓存策略。可以通过记录缓存命中和未命中的次数,以及缓存的数据大小和存储效率来评估缓存的效果。

实现查询缓存的手段和工具

在 Node.js 服务端实现查询缓存时,结合之前提到的关键方面进行说明,我们可以使用以下手段和工具:

1. 内存缓存库

Node.js 中有一些流行的内存缓存库,例如 node-cachememory-cachelru-cache。这些库提供了方便的 API 来实现基于内存的查询缓存。以下是一个示例代码,展示了如何使用 node-cache 库实现查询缓存:

const NodeCache = require('node-cache');
const cache = new NodeCache();

function getDataFromCache(key) {
  const data = cache.get(key);
  if (data) {
    console.log('Fetching data from cache for key:', key);
    return data;
  }
  return null;
}

function setDataToCache(key, data) {
  console.log('Setting data to cache for key:', key);
  cache.set(key, data);
}

2. 数据库缓存

将查询结果存储在数据库中,可以使用键值存储数据库(例如 Redis)或关系数据库来实现查询缓存。这种方式可以提供更持久的缓存,并且适用于多个服务节点共享缓存的情况。以下是一个示例代码,展示了如何使用 Redis 实现查询缓存:

const redis = require('redis');
const client = redis.createClient();

function getDataFromCache(key) {
  return new Promise((resolve, reject) => {
    client.get(key, (err, data) => {
      if (err) {
        reject(err);
      } else {
        console.log('Fetching data from cache for key:', key);
        resolve(data);
      }
    });
  });
}

function setDataToCache(key, data) {
  console.log('Setting data to cache for key:', key);
  client.set(key, data);
}

3. 缓存失效机制

可以通过设置缓存的过期时间或手动使缓存失效来处理缓存的失效。以下是一个示例代码,展示了如何设置缓存的过期时间:

function setDataToCacheWithExpiration(key, data, expirationSeconds) {
  console.log('Setting data to cache for key:', key, 'with expiration:', expirationSeconds, 'seconds');
  cache.set(key, data, expirationSeconds);
}

4. 并发控制

可以使用互斥锁或分布式锁来处理并发访问缓存时的竞态条件。以下是一个示例代码,展示了如何使用 redis 库实现分布式锁来保证对缓存的原子性访问:

const redis = require('redis');
const client = redis.createClient();

function acquireLock(key, expirationSeconds) {
  return new Promise((resolve, reject) => {
    client.set(key, 'locked', 'EX', expirationSeconds, 'NX', (err, result) => {
      if (err) {
        reject(err);
      } else if (result === 'OK') {
        resolve();
      } else {
        reject(new Error('Failed to acquire lock'));
      }
    });
  });
}

function releaseLock(key) {
  return new Promise((resolve, reject) => {
    client.del(key, (err, result) => {
      if (err) {
        reject(err);
      } else {
        resolve();
      }
    });
  });
}

async function getDataWithCacheAndLock(key) {
  const lockKey = key + ':lock';
  try {
    await acquireLock(lockKey, 10); // 10 秒锁的过期时间
    let data = getDataFromCache(key);
    if (!data) {
      // 从数据库获取数据
      data = fetchFromDatabase(key);
      // 将数据设置到缓存
      setDataToCache(key, data);
    }
    return data;
  } finally {
    await releaseLock(lockKey);
  }
}

5. CDN缓存

如果查询的数据是静态文件或资源,例如图片、CSS文件、JavaScript文件等,可以利用CDN(内容分发网络)来实现缓存。CDN在全球分布的边缘节点上缓存静态资源,并根据用户的地理位置选择最近的节点进行访问,从而提高访问速度和性能。

CDN缓存的实现通常是通过在HTTP响应头中设置缓存相关的头部信息,例如Cache-ControlExpiresLast-Modified等,来指示客户端或CDN节点缓存资源的时间和机制。

这种方式适用于静态资源的缓存需求,可以减轻服务器的负载压力,并提供更快速的访问体验。

需要注意的是,CDN缓存通常需要与缓存刷新机制结合使用,以保证数据的更新和一致性。

6. 缓存命中率和效果评估

可以通过日志记录缓存命中和未命中的次数,并使用监控工具(如 Prometheus)来收集和分析数据,评估缓存的命中率和效果。

总结

总的来说,服务端实现缓存在Web应用程序中具有重要的作用和价值。对于提高性能、减轻负载、提高可扩展性、改善用户体验以及降低对外部资源的依赖都非常重要。合理地使用缓存机制可以使Web应用程序更加高效、可靠和可扩展,从而提供更好的用户体验和业务价值。

到此这篇关于详解nodejs如何实现查询缓存的文章就介绍到这了,更多相关nodejs查询缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Node.js中Path 模块的介绍和使用示例小结

    Node.js中Path 模块的介绍和使用示例小结

    Node.js path 模块提供了一些用于处理文件路径的小工具,下面通过本文给大家介绍Node.js中Path 模块的介绍和使用示例小结,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Node.js连接postgreSQL并进行数据操作

    Node.js连接postgreSQL并进行数据操作

    自从MySQL被Oracle收购以后,PostgreSQL逐渐成为开源关系型数据库的首选。这篇文章就给大家介绍了关于Node.js如何连接postgreSQL数据库,并进行数据操作的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • nodejs npm install全局安装和本地安装的区别

    nodejs npm install全局安装和本地安装的区别

    这篇文章主要介绍了nodejs npm install 全局安装和非全局安装的区别,即带参数-g和不带参数-g安装的区别,需要的朋友可以参考下
    2014-06-06
  • Nodejs 搭建简单的Web服务器详解及实例

    Nodejs 搭建简单的Web服务器详解及实例

    这篇文章主要介绍了Nodejs 搭建简单的Web服务器详解及实例的相关资料,并附实例代码和实现效果图,需要的朋友可以参考下
    2016-11-11
  • nodejs多版本管理总结

    nodejs多版本管理总结

    这篇文章主要介绍了nodejs多版本管理的相关知识点,以及实际操作方法和代码,有需要的朋友参考下。
    2018-04-04
  • Node.js 中使用fetch 按JSON格式发post请求的问题解析

    Node.js 中使用fetch 按JSON格式发post请求的问题解析

    最近在测试一个api,可以用curl命令直接访问,指定header相关配置,request body(JSON),成功后返回一个JSON,这篇文章主要介绍了Node.js 中使用fetch 按JSON格式发post请求,需要的朋友可以参考下
    2023-04-04
  • 了解javascript中变量及函数的提升

    了解javascript中变量及函数的提升

    这篇文章主要介绍了关于javascript中变量及函数的提升,下面和小编来一起学习吧
    2019-05-05
  • 详谈nodejs异步编程

    详谈nodejs异步编程

    本文详细介绍了node.js异步编程的分类以及异步编程存在的问题,非常的详尽,非常细致,这里推荐给小伙伴。
    2014-12-12
  • Node.js实现兼容IE789的文件上传进度条

    Node.js实现兼容IE789的文件上传进度条

    这篇文章给大家介绍了如何实现兼容IE789的文件上传进度条,如果你的工作用过上传图片或上传大文件啥的,一般在IE低版本浏览器里,会切换到用flash解决,可是有些人肯定不会为了老旧IE的进度条而去学flash,那么下面来一起看看吧。
    2016-09-09
  • nodejs npm错误Error:UNKNOWN:unknown error,mkdir ''D:\Develop\nodejs\node_global''at Error

    nodejs npm错误Error:UNKNOWN:unknown error,mkdir ''D:\Develop\n

    今天小编就为大家分享一篇关于nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03

最新评论