您现在的位置是:网站首页> 编程资料编程资料
Redis中的String类型及使用Redis解决订单秒杀超卖问题_Redis_
2023-05-27
420人已围观
简介 Redis中的String类型及使用Redis解决订单秒杀超卖问题_Redis_
本系列将和大家分享Redis分布式缓存,本章主要简单介绍下Redis中的String类型,以及如何使用Redis解决订单秒杀超卖问题。
Redis中5种数据结构之String类型:key-value的缓存,支持过期,value不超过512M。
Redis是单线程的,比如SetAll & AppendToValue & GetValues & GetAndSetValue & IncrementValue & IncrementValueBy等等,这些看上去像是组合命令,但实际上是一个具体的命令,是一个原子性的命令,不可能出现中间状态,可以应对一些并发情况。下面我们直接通过代码来看下具体使用。
首先来看下Demo的项目结构:
此处推荐使用的是ServiceStack包,虽然它是收费的,有1小时3600次请求限制,但是它是开源的,可以将它的源码下载下来破解后使用,网上应该有挺多相关资料,有兴趣的可以去了解一波。
一、Redis中与String类型相关的API
首先先来看下Redis客户端的初始化工作:
using System; namespace TianYa.Redis.Init { ////// redis配置文件信息 /// 也可以放到配置文件去 /// public sealed class RedisConfigInfo { ////// 可写的Redis链接地址 /// format:ip1,ip2 /// /// 默认6379端口 /// public string WriteServerList = "127.0.0.1:6379"; ////// 可读的Redis链接地址 /// format:ip1,ip2 /// /// 默认6379端口 /// public string ReadServerList = "127.0.0.1:6379"; ////// 最大写链接数 /// public int MaxWritePoolSize = 60; ////// 最大读链接数 /// public int MaxReadPoolSize = 60; ////// 本地缓存到期时间,单位:秒 /// public int LocalCacheTime = 180; ////// 自动重启 /// public bool AutoStart = true; ////// 是否记录日志,该设置仅用于排查redis运行时出现的问题, /// 如redis工作正常,请关闭该项 /// public bool RecordeLog = false; } }
using ServiceStack.Redis; namespace TianYa.Redis.Init { ////// Redis管理中心 /// public class RedisManager { ////// Redis配置文件信息 /// private static RedisConfigInfo _redisConfigInfo = new RedisConfigInfo(); ////// Redis客户端池化管理 /// private static PooledRedisClientManager _prcManager; ////// 静态构造方法,初始化链接池管理对象 /// static RedisManager() { CreateManager(); } ////// 创建链接池管理对象 /// private static void CreateManager() { string[] writeServerConStr = _redisConfigInfo.WriteServerList.Split(','); string[] readServerConStr = _redisConfigInfo.ReadServerList.Split(','); _prcManager = new PooledRedisClientManager(readServerConStr, writeServerConStr, new RedisClientManagerConfig { MaxWritePoolSize = _redisConfigInfo.MaxWritePoolSize, MaxReadPoolSize = _redisConfigInfo.MaxReadPoolSize, AutoStart = _redisConfigInfo.AutoStart, }); } ////// 客户端缓存操作对象 /// public static IRedisClient GetClient() { return _prcManager.GetClient(); } } }
using System; using TianYa.Redis.Init; using ServiceStack.Redis; namespace TianYa.Redis.Service { ////// redis操作的基类 /// public abstract class RedisBase : IDisposable { ////// Redis客户端 /// protected IRedisClient _redisClient { get; private set; } ////// 构造函数 /// public RedisBase() { this._redisClient = RedisManager.GetClient(); } private bool _disposed = false; protected virtual void Dispose(bool disposing) { if (!this._disposed) { if (disposing) { _redisClient.Dispose(); _redisClient = null; } } this._disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ////// Redis事务处理示例 /// public void Transcation() { using (IRedisTransaction irt = this._redisClient.CreateTransaction()) { try { irt.QueueCommand(r => r.Set("key", 20)); irt.QueueCommand(r => r.Increment("key", 1)); irt.Commit(); //事务提交 } catch (Exception ex) { irt.Rollback(); //事务回滚 throw ex; } } } ////// 清除全部数据 请小心 /// public virtual void FlushAll() { _redisClient.FlushAll(); } ////// 保存数据DB文件到硬盘 /// public void Save() { _redisClient.Save(); //阻塞式Save } ////// 异步保存数据DB文件到硬盘 /// public void SaveAsync() { _redisClient.SaveAsync(); //异步Save } } }
下面直接给大家Show一波Redis中与String类型相关的API:
using System; using System.Collections.Generic; namespace TianYa.Redis.Service { ////// key-value 键值对 value可以是序列化的数据 (字符串) /// public class RedisStringService : RedisBase { #region 赋值 ////// 设置永久缓存 /// /// 存储的键 /// 存储的值 ///public bool Set(string key, string value) { return base._redisClient.Set(key, value); } /// /// 设置永久缓存 /// /// 存储的键 /// 存储的值 ///public bool Set (string key, T value) { return base._redisClient.Set (key, value); } /// /// 带有过期时间的缓存 /// /// 存储的键 /// 存储的值 /// 过期时间 ///public bool Set(string key, string value, DateTime expireTime) { return base._redisClient.Set(key, value, expireTime); } /// /// 带有过期时间的缓存 /// /// 存储的键 /// 存储的值 /// 过期时间 ///public bool Set (string key, T value, DateTime expireTime) { return base._redisClient.Set (key, value, expireTime); } /// /// 带有过期时间的缓存 /// /// 存储的键 /// 存储的值 /// 过期时间 ///public bool Set (string key, T value, TimeSpan expireTime) { return base._redisClient.Set (key, value, expireTime); } /// /// 设置多个key/value /// public void SetAll(Dictionarydic) { base._redisClient.SetAll(dic); } #endregion 赋值 #region 追加 /// /// 在原有key的value值之后追加value,没有就新增一项 /// public long AppendToValue(string key, string value) { return base._redisClient.AppendToValue(key, value); } #endregion 追加 #region 获取值 ////// 读取缓存 /// /// 存储的键 ///public string Get(string key) { return base._redisClient.GetValue(key); } /// /// 读取缓存 /// /// 存储的键 ///public T Get (string key) { return _redisClient.ContainsKey(key) ? _redisClient.Get (key) : default; } /// /// 获取多个key的value值 /// /// 存储的键集合 ///public List Get(List keys) { return base._redisClient.GetValues(keys); } /// /// 获取多个key的value值 /// /// 存储的键集合 ///public List Get (List keys) { return base._redisClient.GetValues (keys); } #endregion 获取值 #region 获取旧值赋上新值 /// /// 获取旧值赋上新值 /// /// 存储的键 /// 存储的值 ///public string GetAndSetValue(string key, string value) { return base._redisClient.GetAndSetValue(key, value); } #endregion 获取旧值赋上新值 #region 移除缓存 /// /// 移除缓存 /// /// 存储的键 ///public bool Remove(string key) { return _redisClient.Remove(key); } /// /// 移除多个缓存 /// /// 存储的键集合 public void RemoveAll(Listkeys) { _redisClient.RemoveAll(keys); } #endregion 移除缓存 #region 辅助方法 /// /// 是否存在缓存 /// /// 存储的键 ///public bool ContainsKey(string key) { return _redisClient.ContainsKey(key); } /// /// 获取值的长度 /// /// 存储的键 ///public long GetStringCount(string key) { return base._redisClient.GetStringCount(key); } /// /// 自增1,返回自增后的值 /// /// 存储的键 ///public long IncrementValue(string key) { return base._redisClient.IncrementValue(key); } /// /// 自增count,返回自增后的值 /// /// 存储的键 /// 自增量 ///public long IncrementValueBy(string key, int count) { return base._redisClient.IncrementValueBy(key, count); } /// /// 自减1,返回自减后的值 /// /// 存储的键 ///public long DecrementValue(string key) { return base._redisClient.DecrementValue(key); } /// /// 自减count,返回自减后的值 /// /// 存储的键 /// 自减量 ///public long DecrementValueBy(string key, int count) { return base._redisClient.DecrementValueBy(key, count); } #endregion 辅助方法 } }
测试如下:
using System; namespace MyRedis { ////// 学生类 /// public class Student { public int Id { get; set; } public string Name { get; set; } public string Remark { get; set; } public string Description { get; set; } } }
using System; using System.Collections.Generic; using TianYa.Redis.Service; using Newtonsoft.Json; namespace MyRedis { ////// ServiceStack API封装测试 五大结构理解 (1小时3600次请求限制--可破解) /// public class ServiceStackTest { ////// String /// key-value的缓存,支持过期,value不超过512M /// Redis是单线程的,比如SetAll & AppendToValue & GetValues & GetAndSetValue & IncrementValue & IncrementValueBy, /// 这些看上去是组合命令,但实际上是一个具体的命令,是一个原子性的命令,不可能出现中间状态,可以应对一些并发情况 /// public static void ShowString() { var student1 = new Student() { Id = 10000, Name = "TianYa" }; using (RedisStringService service = new RedisStringService()) { service.Set("student1", student1); var stu = service.Get("student1"); Console.WriteLine(JsonConvert.Seriali
相关内容
点击排行
本栏推荐
