Redis需要配合其他数据库,这里使用MySql

初始化

安装Nuget包

使用Redis,需要安装StackExchange.Redis包,在Nuget包管理器中搜索这个包并安装在MySql项目里。下面是官方文档

StackExchange.Redis | General purpose redis client

在MySql项目中添加RedisMgr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using StackExchange.Redis;

namespace MySql
{
public class RedisMgr : SingletonPattern<RedisMgr>
{
public ConnectionMultiplexer? m_Redis;//Redis实例
public IDatabase? m_RedisDB;//Redis数据库

public event Action? SaveRedisAction = null;

private long m_LastTime;//上次保存的时间
private const int m_SaveInternal = 300;//保存间隔300秒
public void Init()
{
m_Redis = ConnectionMultiplexer.Connect("localhost");//获取Redis实例
m_RedisDB = m_Redis.GetDatabase(0);//获取实例中的数据库

Thread redisThread = new Thread(SaveRedis);
redisThread.Start();
}
/// <summary>
/// Redis数据储存到MySql
/// </summary>
void SaveRedis()
{
while (true)
{
long timeNow = GetTimeStamp();
if (timeNow - m_LastTime > m_SaveInternal)
{
//执行Redis储存到MySql
if(SaveRedisAction != null)
{
SaveRedisAction.Invoke();
}
m_LastTime = timeNow;
}
Thread.Sleep(1000);
}
}
public static long GetTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc);
return Convert.ToInt64(ts.TotalSeconds);
}
}
}

初始化RedisMgr时,开启一个线程,用于计时并调用SaveRedisAction,将Redis中的Data保存进MySql里。

一般情况下,我们遍历Redis并将其存储进MySql里面,尽量不要遍历MySql再从Redis中存储。

在Program中初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using SimpleServer.Net;
using MongoDB;
using MySql;

namespace SimpleServer
{
internal class Program
{
static void Main(string[] args)
{
MySqlMgr.Instance.Init();
RedisMgr.Instance.Init();//+++
MongoDBMgr.Instance.Init();
ServerSocket.Instance.Init();
Console.ReadLine();
}
}
}

Redis字符串储存和获取

RedisMgr中添加存储和读取字符串的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/// <summary>
/// 储存字符串
/// </summary>
/// <param name="redisKey">Redis指定的Key</param>
/// <param name="redisValue">Redis指定的Value</param>
/// <returns>是否成功储存</returns>
public bool SetString(RedisKey redisKey,RedisValue redisValue)
{
try
{
//有效时间为12小时
TimeSpan timeSpan = new TimeSpan(12, 0, 0);
m_RedisDB?.StringSet(redisKey,redisValue,timeSpan);
return true;
}
catch (Exception ex)
{
Debug.LogError("Redis数据写入错误:" + ex);
return false;
}
}
/// <summary>
/// 读取字符串
/// </summary>
/// <param name="redisKey">Redis指定的Key</param>
/// <returns>Redis指定的Value</returns>
public RedisValue? GetString(RedisKey redisKey)
{
try
{
return m_RedisDB?.StringGet(redisKey);
}
catch (Exception ex)
{
Debug.LogError("Redis数据读取错误:" + ex);
return null;
}
}

注意,虽然这里是存储字符串的方法,但是RedisValue可以是任何值,字节数组、Hash、List都可以。

Redis存储和获取用户类数据

我们将用户数据转化为Json存储到Redis中。

当从Redis里面取数据时,如果Redis里面有值,则直接获取,如果没有,先从MySql里面获取然后再缓存到Redis当中,之后再返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
/// 存类,key只能是MySql数据库主键值
/// </summary>
/// <param name="key">主键</param>
/// <param name="obj"></param>
/// <returns>是否成功</returns>
public bool SetClass(int key,object obj)
{
return SetString(obj.GetType().Name + key,JsonSerializer.Serialize(obj));//在Redis要有唯一的Key值,所以将主键和类名组合起来
}
/// <summary>
/// 取类,key只能是MySql数据库主键值
/// </summary>
/// <typeparam name="T">实体类</typeparam>
/// <param name="key">主键</param>
/// <returns>数据</returns>
public T? GetClass<T>(int key) where T : class
{
RedisValue? redisValue = GetString(typeof(T).Name + key);
if(redisValue != null && redisValue.HasValue)
{
return JsonSerializer.Deserialize<T>(redisValue);
}
else
{
T t = MySqlMgr.Instance.SqlSugarDB!.Queryable<T>().InSingle(key);
if (t != null)
{
SetClass(key,t);
return t;
}
return null;
}
}

Redis定时存储

见下一节