Redis 의 String 유형 및 Redis 를 사용 하여 주문 스 톱 판매 문 제 를 해결 합 니 다.
20615 단어 Redis주문 이 순식간에 초과 판매 되다.분산 캐 시
Redis 에서 5 가지 데이터 구조의 String 형식:key-value 의 캐 시,만 료 지원,value 는 512 M 을 초과 하지 않 습 니 다.
Redis 는 단일 스 레 드 입 니 다.예 를 들 어 SetAll&AppendToValue&Get Values&GetAndSetValue&Increment Value&Increment Value By 등 은 조합 명령 처럼 보이 지만 실제 적 으로 구체 적 인 명령 이 고 원자 적 인 명령 입 니 다.중간 상태 가 나타 날 수 없고 병발 상황 에 대응 할 수 있 습 니 다.다음은 코드 를 통 해 구체 적 인 사용 을 살 펴 보 겠 습 니 다.
먼저 데모 의 프로젝트 구 조 를 살 펴 보 겠 습 니 다.
이곳 에서 추천 하 는 것 은 ServiceStack 가방 입 니 다.비록 비용 이 들 고 1 시간 3600 번 의 요청 제한 이 있 지만 오픈 소스 입 니 다.소스 코드 를 다운로드 하여 풀 어서 사용 할 수 있 습 니 다.인터넷 에 관련 자료 가 많 을 것 입 니 다.관심 이 있 으 면 한 번 알 아 볼 수 있 습 니 다.
1.Redis 에서 String 형식 과 관련 된 API
먼저 Redis 클 라 이언 트 의 초기 화 작업 을 살 펴 보 겠 습 니 다.
using System;
namespace TianYa.Redis.Init
{
/// <summary>
/// redis
///
/// </summary>
public sealed class RedisConfigInfo
{
/// <summary>
/// Redis
/// format:ip1,ip2
///
/// 6379
/// </summary>
public string WriteServerList = "127.0.0.1:6379";
/// <summary>
/// Redis
/// format:ip1,ip2
///
/// 6379
/// </summary>
public string ReadServerList = "127.0.0.1:6379";
/// <summary>
///
/// </summary>
public int MaxWritePoolSize = 60;
/// <summary>
///
/// </summary>
public int MaxReadPoolSize = 60;
/// <summary>
/// , :
/// </summary>
public int LocalCacheTime = 180;
/// <summary>
///
/// </summary>
public bool AutoStart = true;
/// <summary>
/// , redis ,
/// redis ,
/// </summary>
public bool RecordeLog = false;
}
}
using ServiceStack.Redis;
namespace TianYa.Redis.Init
{
/// <summary>
/// Redis
/// </summary>
public class RedisManager
{
/// <summary>
/// Redis
/// </summary>
private static RedisConfigInfo _redisConfigInfo = new RedisConfigInfo();
/// <summary>
/// Redis
/// </summary>
private static PooledRedisClientManager _prcManager;
/// <summary>
/// ,
/// </summary>
static RedisManager()
{
CreateManager();
}
/// <summary>
///
/// </summary>
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,
});
}
/// <summary>
///
/// </summary>
public static IRedisClient GetClient()
{
return _prcManager.GetClient();
}
}
}
using System;
using TianYa.Redis.Init;
using ServiceStack.Redis;
namespace TianYa.Redis.Service
{
/// <summary>
/// redis
/// </summary>
public abstract class RedisBase : IDisposable
{
/// <summary>
/// Redis
/// </summary>
protected IRedisClient _redisClient { get; private set; }
/// <summary>
///
/// </summary>
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);
}
/// <summary>
/// Redis
/// </summary>
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;
}
}
}
/// <summary>
///
/// </summary>
public virtual void FlushAll()
{
_redisClient.FlushAll();
}
/// <summary>
/// DB
/// </summary>
public void Save()
{
_redisClient.Save(); // Save
}
/// <summary>
/// DB
/// </summary>
public void SaveAsync()
{
_redisClient.SaveAsync(); // Save
}
}
}
다음은 Redis 에서 String 형식 과 관련 된 API 를 직접 보 여 드 리 겠 습 니 다.
using System;
using System.Collections.Generic;
namespace TianYa.Redis.Service
{
/// <summary>
/// key-value value ( )
/// </summary>
public class RedisStringService : RedisBase
{
#region
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <returns></returns>
public bool Set(string key, string value)
{
return base._redisClient.Set(key, value);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <returns></returns>
public bool Set<T>(string key, T value)
{
return base._redisClient.Set<T>(key, value);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <param name="expireTime"> </param>
/// <returns></returns>
public bool Set(string key, string value, DateTime expireTime)
{
return base._redisClient.Set(key, value, expireTime);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <param name="expireTime"> </param>
/// <returns></returns>
public bool Set<T>(string key, T value, DateTime expireTime)
{
return base._redisClient.Set<T>(key, value, expireTime);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <param name="expireTime"> </param>
/// <returns></returns>
public bool Set<T>(string key, T value, TimeSpan expireTime)
{
return base._redisClient.Set<T>(key, value, expireTime);
}
/// <summary>
/// key/value
/// </summary>
public void SetAll(Dictionary<string, string> dic)
{
base._redisClient.SetAll(dic);
}
#endregion
#region
/// <summary>
/// key value value,
/// </summary>
public long AppendToValue(string key, string value)
{
return base._redisClient.AppendToValue(key, value);
}
#endregion
#region
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public string Get(string key)
{
return base._redisClient.GetValue(key);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public T Get<T>(string key)
{
return
_redisClient.ContainsKey(key)
? _redisClient.Get<T>(key)
: default;
}
/// <summary>
/// key value
/// </summary>
/// <param name="keys"> </param>
/// <returns></returns>
public List<string> Get(List<string> keys)
{
return base._redisClient.GetValues(keys);
}
/// <summary>
/// key value
/// </summary>
/// <param name="keys"> </param>
/// <returns></returns>
public List<T> Get<T>(List<string> keys)
{
return base._redisClient.GetValues<T>(keys);
}
#endregion
#region
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <param name="value"> </param>
/// <returns></returns>
public string GetAndSetValue(string key, string value)
{
return base._redisClient.GetAndSetValue(key, value);
}
#endregion
#region
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public bool Remove(string key)
{
return _redisClient.Remove(key);
}
/// <summary>
///
/// </summary>
/// <param name="keys"> </param>
public void RemoveAll(List<string> keys)
{
_redisClient.RemoveAll(keys);
}
#endregion
#region
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public bool ContainsKey(string key)
{
return _redisClient.ContainsKey(key);
}
/// <summary>
///
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public long GetStringCount(string key)
{
return base._redisClient.GetStringCount(key);
}
/// <summary>
/// 1,
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public long IncrementValue(string key)
{
return base._redisClient.IncrementValue(key);
}
/// <summary>
/// count,
/// </summary>
/// <param name="key"> </param>
/// <param name="count"> </param>
/// <returns></returns>
public long IncrementValueBy(string key, int count)
{
return base._redisClient.IncrementValueBy(key, count);
}
/// <summary>
/// 1,
/// </summary>
/// <param name="key"> </param>
/// <returns></returns>
public long DecrementValue(string key)
{
return base._redisClient.DecrementValue(key);
}
/// <summary>
/// count,
/// </summary>
/// <param name="key"> </param>
/// <param name="count"> </param>
/// <returns></returns>
public long DecrementValueBy(string key, int count)
{
return base._redisClient.DecrementValueBy(key, count);
}
#endregion
}
}
테스트 는 다음 과 같 습 니 다:
using System;
namespace MyRedis
{
/// <summary>
///
/// </summary>
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
{
/// <summary>
/// ServiceStack API (1 3600 -- )
/// </summary>
public class ServiceStackTest
{
/// <summary>
/// String
/// key-value , ,value 512M
/// Redis , SetAll & AppendToValue & GetValues & GetAndSetValue & IncrementValue & IncrementValueBy,
/// , , , ,
/// </summary>
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<Student>("student1");
Console.WriteLine(JsonConvert.SerializeObject(stu));
service.Set<int>("Age", 28);
Console.WriteLine(service.IncrementValue("Age"));
Console.WriteLine(service.IncrementValueBy("Age", 3));
Console.WriteLine(service.DecrementValue("Age"));
Console.WriteLine(service.DecrementValueBy("Age", 3));
}
}
}
}
using System;
namespace MyRedis
{
/// <summary>
/// Redis:Remote Dictionary Server
/// ( ), 5 ( ), ( ), -- -- -- 。
/// , 。 , 。
/// 。
/// , , , 。Redis ( ), , 。( )
/// Redis , 。
/// Redis , 。 ,Redis 。
/// Redis 5 :String、Hashtable、Set、ZSet List。
/// </summary>
class Program
{
static void Main(string[] args)
{
ServiceStackTest.ShowString();
Console.ReadKey();
}
}
}
실행 결 과 는 다음 과 같 습 니 다.Redis 의 String 유형 은 프로젝트 에서 가장 많이 사 용 됩 니 다.모두 가 알 고 있 을 것 입 니 다.여 기 는 더 이상 설명 을 하지 않 습 니 다.
2.Redis 를 사용 하여 주문 의 초 판매 문 제 를 해결 합 니 다.
우선 주문 의 초판 초과 판매 문제 가 무엇 인지 살 펴 보 겠 습 니 다.
/// <summary>
///
/// :
/// ?
/// , , , 。
/// -1 , , 。
/// 10 , ? 。
/// </summary>
public class OverSellFailedTest
{
private static bool _isGoOn = true; //
private static int _stock = 0; //
public static void Show()
{
_stock = 10;
for (int i = 0; i < 5000; i++)
{
int k = i;
Task.Run(() => //
{
if (_isGoOn)
{
long index = _stock;
Thread.Sleep(100); //
if (index >= 1)
{
_stock = _stock - 1; //
Console.WriteLine($"{k.ToString("0000")} , {index}");
// ,
}
else
{
if (_isGoOn)
{
_isGoOn = false;
}
Console.WriteLine($"{k.ToString("0000")} , {index}");
}
}
else
{
Console.WriteLine($"{k.ToString("0000")} ......");
}
});
}
}
}
OverSellFailed Test.How()를 실행 한 결 과 는 다음 과 같 습 니 다.운행 결 과 를 보면 한 상품 이 여러 사람 에 게 팔 렸 을 뿐만 아니 라 주문 수가 상품 수 를 초과 하 는 것 도 전형 적 인 초 살 과 매 문제 임 을 알 수 있다.
다음은 레 디 스 를 어떻게 사용 하여 주문 의 초 판매 문 제 를 해결 하 는 지 살 펴 보 겠 습 니 다.
/// <summary>
/// Redis
/// :
/// 1、Redis -- --
/// 2、 Redis, , , , ,
/// redis, ,
/// 3、Redis , ,
/// 4、 / --- down ,
/// 5、 --- , , ( )
/// </summary>
public class OverSellTest
{
private static bool _isGoOn = true; //
public static void Show()
{
using (RedisStringService service = new RedisStringService())
{
service.Set<int>("Stock", 10); //
}
for (int i = 0; i < 5000; i++)
{
int k = i;
Task.Run(() => //
{
using (RedisStringService service = new RedisStringService())
{
if (_isGoOn)
{
long index = service.DecrementValue("Stock"); // 1
if (index >= 0)
{
Console.WriteLine($"{k.ToString("0000")} , {index}");
//service.IncrementValue("Stock"); // 1,
// ,
}
else
{
if (_isGoOn)
{
_isGoOn = false;
}
Console.WriteLine($"{k.ToString("0000")} , {index}");
}
}
else
{
Console.WriteLine($"{k.ToString("0000")} ......");
}
}
});
}
}
}
OverSellTest.How()를 실행 한 결 과 는 다음 과 같 습 니 다.운행 결 과 를 보면 레 디 스 를 사용 하면 주문 의 초판 초과 판매 문 제 를 잘 해결 할 수 있 음 을 알 수 있다.
이로써 본 고 는 모두 소개 되 었 습 니 다.당신 에 게 깨 우 침 이 있다 고 생각 되면 좋아요 를 눌 러 주세요!!
데모 소스 코드:
링크:https://pan.baidu.com/s/1vukiDxOLQYZX4Qd94izMpQ추출 코드:bdfm
이 글 은 블 로 거들 이 심혈 을 기울 여 작성 하여 옮 겨 실 었 습 니 다.이 원문 링크 를 유지 하 십시오.https://www.cnblogs.com/xyh9039/p/13979522.html
저작권 성명:만약 유사 가 있 으 면 순 전 히 우연 의 일치 입 니 다.권리 침해 가 있 으 면 즉시 본인 에 게 연락 하여 수정 하 십시오.감사합니다!!
레 디 스 의 String 유형 및 레 디 스 를 이용 한 주문 스 톱 오 버 문 제 를 해결 하 는 글 을 소개 합 니 다.더 많은 관련 레 디 스 가 주문 스 톱 오 버 문 제 를 해결 하 는 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 도 많은 지원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
그래프 구조를 무상으로 취급할 수 없는 것은 싫기 때문에, redisgraph를 WSL2에 극치고 설치해 보았습니다.제목은 만우절이므로. 그렇다, 역시, 앞으로는 그래프 구조 데이터베이스라고 생각했다. 생각한 것은 몇 년 전인가. 전부터 Neo4j는 시험하고 있지만, 영업 분들로부터 상용 라이센스가 높다고 가르쳐 주었으므로, 전전...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.