详解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查询缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题

    解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题

    今天小编就为大家分享一篇解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 在Node.js中使用TypeScript的方法示例

    在Node.js中使用TypeScript的方法示例

    在前端开发中,随着TypeScript的不断普及,越来越多的开发者使用TypeScript进行开发,然而,在后端开发中,在Node.js中使用 TypeScript还是相对较少见的,这篇文章将介绍如何在Node.js中配置TypeScript ,以及如何使用TypeScript来开发高质量的应用程序
    2023-06-06
  • Node.js实现用户身份验证和授权的示例代码

    Node.js实现用户身份验证和授权的示例代码

    在web开发中,我们常常需要对一些敏感的url进行访问权限控制,本文主要介绍了Node.js实现用户身份验证和授权的示例代码,具有一定的参考价值,感兴趣的了解一下
    2024-02-02
  • 详解NodeJs项目 CentOs linux服务器线上部署

    详解NodeJs项目 CentOs linux服务器线上部署

    这篇文章主要介绍了NodeJs项目 CentOs linux服务器线上部署,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • NodeJS使用递归算法和遍历算法来遍历目录的方法

    NodeJS使用递归算法和遍历算法来遍历目录的方法

    遍历目录是操作文件时的一个常见需求,比如写一个程序,需要找到并处理指定目录下的所有JS文件时,就需要遍历整个目录,NodeJS遍历目录可以使用递归算法、遍历算法,遍历算法又分为同步遍历、异步遍历两种,本文介绍NodeJS使用递归算法和遍历算法来遍历目录的方法
    2023-11-11
  • 使用Phantomjs和Node完成网页的截屏快照的方法

    使用Phantomjs和Node完成网页的截屏快照的方法

    这篇文章主要介绍了使用Phantomjs和Node完成网页的截屏快照的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Node.js中同步和异步编程的区别及使用方法

    Node.js中同步和异步编程的区别及使用方法

    在Node.js中,同步和异步编程是两种不同的处理方式。同步方式会阻塞程序的执行,而异步方式则不会。通过掌握它们的区别和使用方法,可以更好地实现程序的性能优化和功能扩展。同时,需要注意异步编程中的回调地狱问题,使用Promise可以更好地处理异步编程
    2023-05-05
  • 用Nodejs实现在终端中炒股的实现

    用Nodejs实现在终端中炒股的实现

    这篇文章主要介绍了用Nodejs实现在终端中炒股的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • node.JS md5加密中文与php结果不一致的解决方法

    node.JS md5加密中文与php结果不一致的解决方法

    本篇文章主要介绍了node.JS md5加密中文与php结果不一致的解决方法,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-05-05
  • 切换Node.js镜像源的方法详解

    切换Node.js镜像源的方法详解

    Node.js 是一个非常流行的 JavaScript 运行环境,拥有许多强大的功能和库,使得它在 Web 开发、服务器端编程等领域中广泛使用,在本文中,我们将介绍如何切换 Node.js 的镜像源,并提供一些思考和难点,帮助读者更好地理解这个问题,需要的朋友可以参考下
    2024-01-01

最新评论