对于高频/大流量访问的数据接口,我们都会使用缓存进行优化,从而减少对数据库的连接压力及加快接口数据的返回,从而达到一定的性能优化
这里我们使用 MySQL 和 Redis 两个数据库进行对比

首先,我们先单独测试下,直接连接MySQL读取数据以及直接连接Redis读取数据的一个性能差距
说明:为了保证硬件性能差异的问题,我们的 MySQL 和 Redis 在同一台服务器中(4核4G)

MySQL使用EF6进行操作,Redis使用 RedisSQLHelper(基于StackExchange.Redis)
下面代码省略许多,看做伪代码即可

public string TestMysql()
{
    var data = demo001Entities.Article.First(p => p.Id == 1);
    return ToJson(data);
}


public string TestRedis()
{
    var data = redisHelper.StringGet("1");
    return data;
}

测试一:
我们使用 Apache 的 AB 压测工具进行分别压测(不过由于Demo中的SQL操作简单,所以差距并不明显,如果是较为复杂并且比较消耗时间和性能的SQL,明显会比较大)

ab -n 2000 -c 400 localhost:50493/home/TestMysql

TestMysql的

TestRedis的

测试二:
直接在程序内部进行多次调用

public string Index(int n)
{
    //TestMysql
    DateTime mysqlStime = DateTime.Now;
    for (int i = 0; i < n; i++)
    {
        TestMysql();
    }
    DateTime mysqlEtime = DateTime.Now;

    //TestRedis
    DateTime redisStime = DateTime.Now;
    for (int i = 0; i < n; i++)
    {
        TestRedis();
    }
    DateTime redisEtime = DateTime.Now;
     
    string mysql = "mysql:" + (mysqlEtime - mysqlStime).TotalSeconds+"s";
    string redis = "redis:" + (redisEtime - redisStime).TotalSeconds+"s";

    return mysql + " | " + redis;
}

100次

1000次

5000次

综上可以看出,使用 Redis 作为缓存中间件后,性能的提升还是可以相当明显的


接下来,我们用 .Net 的方式进行 Redis 缓存的实现,基本流程如下

public string Index(string n)
{
    string result = "", comeFrom = "";
    //判断缓存是否存在数据
    var redisData = redisHelper.StringGet(n);
    if (redisData == null)
    {
        comeFrom = "mysql";
        int id = Convert.ToInt32(n);
        result = ToJson(demo001Entities.Article.First(p => p.Id == id));
        //写入缓存
        redisHelper.StringSet(n, result);
    }
    else
    { 
        comeFrom = "redis";
        result = redisData;
    } 
    return comeFrom + "|" + result;
}

效果就是,首次获取数据的时候如果不存在,直接获取 MySQL 里面的数据进行返回,第二次获取相同的数据的时候,就会直接从 Redis 缓存中进行获取

第一次

第二次

以上是简单的实现方式,实际情况中,我们还需要思考 Redis 与数据库的数据同步问题,缓存失效时间(数据淘汰策略),缓存击穿,缓存雪崩等问题