NewLife.Redis基础教程

X组件缓存架构以ICache接口为核心,包括MemoryCache、Redis和DbCache实现,支持FX和netstandard2.0! 后续例程与使用说明均以Redis为例,各缓存实现类似。

Redis组件:Nuget包NewLife.Redis,源码 https://github.com/NewLifeX/NewLife.Redis

X组件:Nuget包NewLife.Core,源码 https://github.com/NewLifeX/X

一、内存缓存 MemoryCache

MemoryCache核心是并行字典ConcurrentDictionary,由于省去了序列化和网络通信,使得它具有千万级超高性能(普通台式机实测1600万tps)。 MemoryCache支持过期时间,默认容量10万个,未过期key超过该值后,每60秒根据LRU清理溢出部分。 常用于进程内千万级以下数据缓存场景。

// 缓存默认实现Cache.Default是MemoryCache,可修改
//var ic = Cache.Default;
//var ic = new MemoryCache();

二、基础 Redis

Redis实现标准协议以及基础字符串操作,完整实现由独立开源项目NewLife.Redis提供。 采取连接池加同步阻塞架构,具有超低延迟(200~600us)以及超高吞吐量(实测222万ops/900Mbps)的特点。 在物流行业大数据实时计算中广泛应有,经过日均100亿次调用量验证。

// 实例化Redis,默认端口6379可以省略,密码有两种写法
//var ic = Redis.Create("127.0.0.1", 7);
var ic = Redis.Create("pass@127.0.0.1:6379", 7);
//var ic = Redis.Create("server=127.0.0.1:6379;password=pass", 7);
ic.Log = XTrace.Log; // 调试日志。正式使用时注释

三、数据库 DbCache

DbCache属于实验性质,采用数据库存储数据,默认SQLite。

四、基本操作

在基本操作之前,我们先做一些准备工作:

新建控制台项目,并在入口函数开头加上  XTrace.UseConsole();  ,这是为了方便查看调试日志 具体测试代码之前,需要加上前面MemoryCache或Redis的实例化代码 准备一个模型类User

class User
{
    public String Name { get; set; }
    public DateTime CreateTime { get; set; }
}

添删改查:

var user = new User { Name = "NewLife", CreateTime = DateTime.Now };
ic.Set("user", user, 3600);
var user2 = ic.Get<User>("user");
XTrace.WriteLine("Json: {0}", ic.Get<String>("user"));
if (ic.ContainsKey("user")) XTrace.WriteLine("存在!");
ic.Remove("user");

执行结果:

14:14:25.990  1 N - SELECT 7
14:14:25.992  1 N - => OK
14:14:26.008  1 N - SETEX user 3600 [53]
14:14:26.021  1 N - => OK
14:14:26.042  1 N - GET user
14:14:26.048  1 N - => [53]
14:14:26.064  1 N - GET user
14:14:26.065  1 N - => [53]
14:14:26.066  1 N - Json: {"Name":"NewLife","CreateTime":"2018-09-25 14:14:25"}
14:14:26.067  1 N - EXISTS user
14:14:26.068  1 N - => 1
14:14:26.068  1 N - 存在!
14:14:26.069  1 N - DEL user
14:14:26.070  1 N - => 1

保存复杂对象时,默认采用Json序列化,所以上面可以按字符串把结果取回来,发现正是Json字符串。 Redis的strings,实质上就是带有长度前缀的二进制数据,[53]表示一段53字节长度的二进制数据。

五、集合操作

GetAll/SetAll 在Redis上是很常用的批量操作,同时获取或设置多个key,一般有10倍以上吞吐量。

批量操作:

var dic = new Dictionary<String, Object>
{
    ["name"] = "NewLife",
    ["time"] = DateTime.Now,
    ["count"] = 1234
};
ic.SetAll(dic, 120);

var vs = ic.GetAll<String>(dic.Keys);
XTrace.WriteLine(vs.Join(",", e => $"{e.Key}={e.Value}"));

执行结果:

MSET name NewLife time 2018-09-25 15:56:26 count 1234
=> OK
EXPIRE name 120
EXPIRE time 120
EXPIRE count 120
MGET name time count
name=NewLife,time=2018-09-25 15:56:26,count=1234

集合操作里面还有 GetList/GetDictionary/GetQueue/GetSet 四个类型集合,分别代表Redis的列表、哈希、队列、Set集合等。 基础版Redis不支持这四个集合,完整版NewLife.Redis支持,MemoryCache则直接支持。

六、高级操作

  • Add 添加,当key不存在时添加,已存在时返回false。
  • Replace 替换,替换已有值为新值,返回旧值。
  • Increment 累加,原子操作
  • Decrement 递减,原子操作

高级操作:

var flag = ic.Add("count", 5678);
XTrace.WriteLine(flag ? "Add成功" : "Add失败");
var ori = ic.Replace("count", 777);
var count = ic.Get<Int32>("count");
XTrace.WriteLine("count由{0}替换为{1}", ori, count);

ic.Increment("count", 11);
var count2 = ic.Decrement("count", 10);
XTrace.WriteLine("count={0}", count2);

执行结果:

SETNX count 5678
=> 0
Add失败
GETSET count 777
=> 1234
GET count
=> 777
count由1234替换为777
INCRBY count 11
=> 788
DECRBY count 10
=> 778
count=778

七、性能测试

Bench 会分根据线程数分多组进行添删改压力测试。 rand 参数,是否随机产生key/value。 batch 批大小,分批执行读写操作,借助GetAll/SetAll进行优化。

Redis默认设置AutoPipeline=100,无分批时打开管道操作,对添删改优化。

Redis性能测试[随机],批大小[100],逻辑处理器 40 个 2,400MHz Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz
测试 100,000 项,  1 线程
赋值 100,000 项,  1 线程,耗时     418ms 速度   239,234 ops
读取 100,000 项,  1 线程,耗时     520ms 速度   192,307 ops
删除 100,000 项,  1 线程,耗时     125ms 速度   800,000 ops
测试 200,000 项,  2 线程
赋值 200,000 项,  2 线程,耗时     548ms 速度   364,963 ops
读取 200,000 项,  2 线程,耗时     549ms 速度   364,298 ops
删除 200,000 项,  2 线程,耗时     315ms 速度   634,920 ops
测试 400,000 项,  4 线程
赋值 400,000 项,  4 线程,耗时     694ms 速度   576,368 ops
读取 400,000 项,  4 线程,耗时     697ms 速度   573,888 ops
删除 400,000 项,  4 线程,耗时     438ms 速度   913,242 ops
测试 800,000 项,  8 线程
赋值 800,000 项,  8 线程,耗时   1,206ms 速度   663,349 ops
读取 800,000 项,  8 线程,耗时   1,236ms 速度   647,249 ops
删除 800,000 项,  8 线程,耗时     791ms 速度 1,011,378 ops
测试 4,000,000 项, 40 线程
赋值 4,000,000 项, 40 线程,耗时   4,848ms 速度   825,082 ops
读取 4,000,000 项, 40 线程,耗时   5,399ms 速度   740,877 ops
删除 4,000,000 项, 40 线程,耗时   6,281ms 速度   636,841 ops
测试 4,000,000 项, 64 线程
赋值 4,000,000 项, 64 线程,耗时   6,806ms 速度   587,716 ops
读取 4,000,000 项, 64 线程,耗时   5,365ms 速度   745,573 ops
删除 4,000,000 项, 64 线程,耗时   6,716ms 速度   595,592 ops

Redis组件:Nuget包NewLife.Redis,源码 https://github.com/NewLifeX/NewLife.Redis

X组件:Nuget包NewLife.Core,源码 https://github.com/NewLifeX/X

如果你喜欢我们的开源项目,到github赏个star呗^_^

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏XAI

微信OAuth授权获取用户OpenId-JAVA(个人经验)

源码在这里。https://zb.oschina.net/market/opus/1444646_161 维护服务器。一份5元。自愿购买

3.2K80
来自专栏运维一切

laravel自定义错误页面 原

app\Exceptions\handler.php 在render的时候就携带了这个异常

12630
来自专栏黑泽君的专栏

SolrCloud搭建 + zookeeper集群搭建 + 搜索功能切换到集群版 + httpclient学习 + 全局异常处理器

索引集合包括两个Shard(Shard1和Shard2),Shard1和Shard2分别由三个Core组成,其中一个Leader两个Replication,L...

20820
来自专栏我有一个梦想

设计模式学习笔记-命令模式

1. 概述   将一个请求封装为一个对象(即我们创建的Command对象),从而使你可用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以及支持可撤销的...

205100
来自专栏技术博客

Asp.Net Mvc3.0(MEF依赖注入实例)

在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍。本节主要来介绍如何在Asp.Ne...

9920
来自专栏NetCore

【翻译】在Visual Studio中使用Asp.Net Core MVC创建第一个Web Api应用(二)

运行应用 In Visual Studio, press CTRL+F5 to launch the app. Visual Studio launches a...

24780
来自专栏程序你好

不同的.Net版本客户端软件调用Java Web Service区别

最近的系统中需要.Net开发的离线端软件通过Web Service技术和Java开发的在线系统进行数据交互。

12130
来自专栏NetCore

Linq to Sql 更新数据时容易忽略的问题

越来越多的朋友喜欢用Linq to Sql来进行开发项目了,一般我们都会遇到CRUD等操作,不可否认,在查询方面Linq真的带来很大的便利,性能方面也表现不错,...

20980
来自专栏SDNLAB

使用Python-Requests实现ODL对OVS的流表下发

目标 通过ODL,在OVS上添加如下的一个group # ovs-vsctl add-br br0 # ovs-vsctl set bridge br0 pr...

40350
来自专栏木宛城主

基于Socket的网络聊天室编程(第一版)

一:什么是套接字 在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常...

30350

扫码关注云+社区

领取腾讯云代金券