nodejs集群

高并发架构

在业务的最初期,由于业务和用户的体量比较小,可能采用单机就足够了。随着业务的增长,用户量和并发请求量都会不断上升。当增长到一定的瓶颈的时候,系统能否抗住压力,就需要采取一些方案了。这就是著名的C10K,甚至C100K,C1000K的问题。

一般我们会从2个层面去解决这些问题:硬件层面和软件架构层面。

硬件层面

硬件层面,我们可以进行纵向扩展和横向扩展。

纵向扩展就是增加硬件的性能和配置。这个很好理解,比如采用配置更高的服务器设备和更大带宽的网络,数据库采用Oracle。纵向扩展实施起来简单,缺点是费钱;而且硬件的性能都有上限,最终还是要靠横向扩展。

横向扩展就是购买多台机器,通过负载均衡来提供服务。比如:1台不行就10台,10台不行就100台。数据库也是,数据量太大就分库分表。

软件架构层面

软件层面可以细分为很多方面,比如缓存,消息队列,数据库优化,微服务架构。

对于大多数系统,数据库都是“压倒骆驼的最后一根稻草”,是最容易引起瓶颈的问题所在。我们从架构层面尽量减少到达数据库的访问。

缓存其实就是将高频访问的数据进行缓存,获取的时候先从缓存中取,然后返回给客户端;这样就大大减少了对数据库的访问次数。缓存是成本最低,见效最高的一种方案

消息队列可以用来应对秒杀场景的高并发,我们将所有的请求看做消息存储到消息队列,然后立即返回给客户端。然后在按照顺序从队列中取消息,一条一条的处理;可以避免系统在海量并发下造成崩溃。

数据库优化其实就SQL技巧和索引的优化了;也可以采用适合应用场景的数据库。比如如果没有事务要求,可以采用性能更高的NoSQL数据库(比如MongoDB);如果有大量的搜索需求,可以采用ElasticSearch。

微服务架构是将单体架构进行拆分,可以更好的优化具有性能瓶颈的服务,提升单个服务的性能。

Redis使用

介绍

Redis是目前最流行的缓存数据库,它将数据存到内存中,并支持持久化;所以读取速度非常快,普通机器也能轻松达到10w+/s;并支持丰富的数据类型,如key/value,list,map,set等。

官网:https://redis.io/

中文网站:http://www.redis.net.cn/

redis-cli使用

redis-cli是Redis提供的命令行客户端,可以方便执行Redis命令。简单演示命令行的操作:

  • get/set
  • del xxx
  • rpush/lrange
node_redis客户端

Redis有各种语言的客户端实现,就像我们使用MySQL驱动连接MySQL数据库一样,我们需要使用NodeJs的Redis客户端去操作Redis数据库。在NodeJs中最为好用的是node_redis实现。

node_redis:https://github.com/NodeRedis/node_redis

具体做法是:先将热点数据存储到Redis中,业务模块取数据的时候优先从缓存中获取。

代码演示热数据的准备和从缓存中取数据:

var redis = require("redis"),
    client = redis.createClient("redis://localhost:6379");
require("./db")
let util = require("util");
let promisifyGet = util.promisify(client.get).bind(client);
let promisifyLrange = util.promisify(client.lrange).bind(client);
let promisifyLlen = util.promisify(client.llen).bind(client);
let Category = require("./model/category");

let config = require("./config");

// 连接失败
client.on("error", function () {
    console.log("Error " + err);
});

// 设置键值对
async function testSetKeyValue() {
    // 设置数据
    client.set("ka", "va");
    // 获取数据
    let result = await promisifyGet("ka");
    console.log(result);

}

// 设置List集合
async function testSetList() {

    client.rpush("mylist", "1", "2", "3", "1");

    // 获取数据
    let result = await promisifyLrange("mylist", 0, -1);
    console.log(result);

}

// 添加分类
async function addCategory() {
    let result = await Category.find();

    result.forEach(item => {
        client.rpush("categories", JSON.stringify(item));
    })
}

// 获取分类
async function getCategoryByPage(page = 1) {
    // 判断集合的长度
    let length = await promisifyLlen("categories");
    // 长度大于0,说明Redis有数据,就从Redis中获取数据
    if (length > 0) {

        let skip = (page - 1) * config.PAGE_SIZE;
        let stop = page * config.PAGE_SIZE - 1;
        // 获取分页数据
        let result = await promisifyLrange("categories", skip, stop);
        console.log(result);
    } else {
        console.log("Redis中没有数据,从Mongodb中获取数据");
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值