Redis初识

数据类型

string

图片 1

list

双向链表、允许再度,协理lpush/rpush和lpop/rpop;完毕音讯队列等;

图片 2

set

不一致意再一次,内部是哈希表达成、查找/删除/插入均O(1); 集合提供SINTE汉兰达、SUNION、SDIFF分别帮衬交集、并集、差集操作。

图片 3

hash

键值对(父键+子键:值)。存储键key的三个属性数据,完全能够用Json格式存款和储蓄、直接当做string类型操作,但对质量有震慑,所以Redis提议Hash类型。

图片 4 

正如,图一是屡见不鲜的key/value结构,必要封装一个指标保存value的音讯;图二是Redis的Hash类型:

图片 5

zset

不变键值对(父键+成员:分值),键值对实在是成员和分值(Member-Score)的照耀关系(字符串成员member与浮点数分值score之间的平稳映射,按分值大小排序),分值必须为浮点数; 既能够依据成员访问成分(同散列),又有啥不可依照分值按序访问成分结构。

图片 6

/// <summary>
/// 构造函数
/// </summary>
/// <param name=”OpenPooledRedis”>是或不是开启缓冲池</param>
public RedisTool(bool OpenPooledRedis = false)
{
if (OpenPooledRedis)
{
prcm = CreateManager(new[] { “123456@127.0.0.1:6379” }, new[] {
“123456@127.0.0.1:6379” });
Redis = prcm.GetClient() as RedisClient;
}
}

选用场景

率先,将Redis与SQL Server/MySQL等对比一下:

  • Redis的持久化是外加成效,且其flushdb、flushall命令会直接清空数据库,
    SQL Server/MySQL的持久化是基本功效;
  • Redis全量持久数据从内部存款和储蓄器到磁盘、大数目下影响属性,SQL
    Server/MySQL增量持久化被涂改的数目;

运用场景

 - 在主页中显示最新的项目列表;
 - 删除和过滤:lrem;
 - 排行榜(Leader Board)及相关问题;
 - 按照用户投票和时间排序;
 - 过期项目处理:unix时间作为得分;
 - 计数(Counting Stuff):INCR,DECR命令构建计数器系统;
 - 特定时间内的特定项目:Redis特色特性;
 - 实时分析正在发生的情况,用于数据统计与防止垃圾邮件等;
 - Pub/Sub:发布订阅机制;
 - 队列(Priority Queue);
 - 缓存(Caching);  

下一场交到使用Redis中的几点注意事项:

  • keys * —>  scan
  • 提议利用hash
  • expire安装key的并存时间 + volatile-lru策略;
  • Redis所在机械物理内部存款和储蓄器使用最好不用跨越实际内部存款和储蓄器总量的十分六;

以及经过阅读 ALCA in
Redis-land
 获得的提议:

图片 7

参考:Redis应用场景; Redis小编谈Redis应用场景; Redis应用提出

//私下认可缓存过期时刻单位秒
public int secondsTimeOut = 30 * 60;

Redis for C#

初识Redis时接触到的.Net-Redis组件是ServiceStack.Redis,其V3连串的流行版本是:ServiceStack.Redis.3.9.29.0

ServiceStack.Redis

ServiceStack.Common.dll
ServiceStack.Interfaces.dll
ServiceStack.Redis.dll
ServiceStack.Text.dll

问询RedisClient类的现实音讯:

  • 基本操作

    public void Init();
    public bool ContainsKey(string key);
    public bool Remove(string key);
    public void RemoveByPattern(string pattern);
    public void RemoveByRegex(string pattern);
    public IEnumerable GetKeysByPattern(string pattern);
    public List SearchKeys(string pattern);
    public List GetAllKeys(); // 数据库内的全部键(慎用)
    public string GetRandomKey();
    public T Get(string key);
    public IRedisTypedClient As(); // / 重要 /
    public bool Add(string key, T value [, DateTime expiresAt]); // [设置过期时间]
    public bool Add(string key, T value [, TimeSpan expiresIn]);
    public bool Set(string key, T value [, DateTime expiresAt]); // [设置过期时间]
    public bool Set(string key, T value [, TimeSpan expiresIn]);
    public bool ExpireEntryAt(string key, DateTime expireAt); // 设置过期时间
    public bool ExpireEntryIn(string key, 提姆eSpan expireIn);
    public TimeSpan GetTimeToLive(string key); // TTL时间
    public long DecrementValue(string key); // 减
    public long DecrementValueBy(string key, int count);
    public long IncrementValue(string key); // 增
    public long IncrementValueBy(string key, int count);

  • string

    public long GetStringCount(string key);
    public string GetValue(string key);
    public void SetValue(string key, string value [, TimeSpan expireIn]);
    public void RenameKey(string fromName, string toName);
    public int AppendToValue(string key, string value);
    public string GetAndSetValue(string key, string value);
    public string GetSubstring(string key, int fromIndex, int toIndex);
    public List GetValues(List keys);
    public Dictionary GetValuesMap(List keys);

  • List  

    // 基本操作
    public int GetListCount(string listId);
    public int RemoveItemFromList(string listId, string value);
    public string RemoveStart/End/AllFromList(string listId);
    public void SetItemInList(string listId, int listIndex, string value);
    public void AddItemToList(string listId, string value);
    public void AddRangeToList(string listId, List values);
    public List GetAllItemsFromList(string listId);
    public string GetItemFromList(string listId, int listIndex);
    public List GetRangeFromList(string listId, int startingFrom, int endingAt);
    public List GetRangeFromSortedList(string listId, int startingFrom, int endingAt);
    public List GetSortedItemsFromList(string listId, SortOptions sortOptions);
    public List GetValues(List keys);
    public Dictionary GetValuesMap(List keys);
    // List作为队列
    public void EnqueueItemOnList(string listId, string value);
    public string DequeueItemFromList(string listId);
    // List作为栈
    public void PushItemToList(string listId, string value);
    public string PopItemFromList(string listId);
    public string PopAndPushItemBetweenLists(string fromListId, string toListId);

  • Set

    public int GetSetCount(string setId);
    public bool SetContainsItem(string setId, string item);
    public void RemoveItemFromSet(string setId, string item);
    public void AddItemToSet(string setId, string item);
    public void AddRangeToSet(string setId, List items);
    public HashSet GetAllItemsFromSet(string setId);
    public string GetRandomItemFromSet(string setId);
    public List GetSortedEntryValues(string setId, int startingFrom, int endingAt);
    public HashSet GetDifferencesFromSet(string fromSetId, params string[] withSetIds);
    public HashSet GetIntersectFromSets(params string[] setIds);
    public HashSet GetUnionFromSets(params string[] setIds);
    public void StoreDifferencesFromSet(string intoSetId, string fromSetId, params string[] withSetIds);
    public void StoreIntersectFromSets(string intoSetId, params string[] setIds);
    public void StoreUnionFromSets(string intoSetId, params string[] setIds);
    public void MoveBetweenSets(string fromSetId, string toSetId, string item);
    public string PopItemFromSet(string setId); 

  • Hash

    public int GetHashCount(string hashId);
    public bool HashContainsEntry(string hashId, string key);
    public bool RemoveEntryFromHash(string hashId, string key);
    public bool SetEntryInHash(string hashId, string key, string value);
    public List GetHashKeys(string hashId);
    public List GetHashValues(string hashId);
    public Dictionary GetAllEntriesFromHash(string hashId);
    public string GetValueFromHash(string hashId, string key);
    public List GetValuesFromHash(string hashId, params string[] keys);
    public T GetFromHash(object id);

  • SortedSet(zset)

    public int GetSortedSetCount(string setId);
    public bool SortedSetContainsItem(string setId, string value);
    public bool RemoveItemFromSortedSet(string setId, string value);
    public bool AddItemToSortedSet(string setId, string value [, double score]);
    public bool AddRangeToSortedSet(string setId, List values [, double score]);
    public List GetRangeFromSortedSet(string setId, int fromRank, int toRank);
    public IDictionary GetRangeWithScoresFromSortedSet(string setId, int fromRank, int toRank);
    public List GetAllItemsFromSortedSetDesc;
    public IDictionary GetAllWithScoresFromSortedSet(string setId);

当中,方法 public IRedisTypedClient<T>
As<T>(); 搭配接口 public interface
IRedisTypedClient<T> : IEntityStore<T>{} 和
public interface IEntityStore<T>{}
中提供的措施能够做到种种操作。

在V3.0版本的基本功上,其V4.0版本 ServiceStack.Redis-4.0.52 提供了越来越多的法子:

  • Scan方法;
  • 获得设置配置新闻;
  • 支持Lua脚本; 

    public RedisText Custom(params object[] cmdWithArgs); // 执行命令
    public RedisClient CloneClient();
    public string GetClient();
    public void SetClient(string name);
    public void KillClient(string address);
    public void ChangeDb(long db);
    public DateTime GetServerTime();
    public DateTime ConvertToServerDate(DateTime expiresAt);
    public List> GetClientsInfo();
    public string GetConfig(string configItem);
    public void SetConfig(string configItem, string value);
    public void SaveConfig();
    public void ResetInfoStats();

其中,Custom()方法能够执行绝超越八分之四的Redis命令,ServiceStack.Redis.Commands概念命令,用于Custom()方法的第②个参数:

public static class Commands{   
        public static readonly byte[] CommandName;
}   

参考

StackExchange.Redis

是因为瑟维斯Stack.Redis的V4.0版本商业化初始收费,推荐使用:StackExchange.Redis

StackExchange.Redis是专为.Net/C#的Redis客户端API,如今被StackOverFlow使用、微软官方RedisSessionStateProvider也选用StackExchange.Redis达成。

StackExchange.Redis的中坚是ConnectionMultiplexer类(线程安全),在命名空间StackExchange.Redis中定义,封装了Redis服务的操作细节,该类的实例被全数应用程序域共享和选定。

ConnectionMultiplexer redisClient = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redisClient .GetDatabase();

其基础和应用待学习…

参考

 


参考

#region 链表操作

持久化

内部存款和储蓄器提供主存款和储蓄援助、硬盘作持久性存款和储蓄。私下认可开启本田CR-VDB情势,暗中同意优先加载AOF文件。二次性将数据加载到内部存款和储蓄器中,壹次性预热。

问题:当服务器被关门时,服务器内部存款和储蓄器存款和储蓄的数目将何去何从?

RDB .vs. AOF

  • CRUISERDB情势二进制方式存款和储蓄数据,文件较小且格式紧密(奇骏DB文件的蕴藏格式和Redis数据在内存中的编码格式一致)、加载速度快;AOF形式文本文件扩展写操作命令,文件较大、消息冗余,加载速度慢,但rewrite命令会压缩aof文件;
  • 奥德赛DB格局按布置的save策略实现定期批量数额存储、效能相对较高;AOF情势准实时日志记录、成效相对较低;
  • 比较本田CR-VDB形式,AOF情势可靠性较高、最少的多少丢失和较高的数据苏醒能力;

不重启Redis从奥迪Q7DB方式切换来AOF格局

redis-cli> config set appendonly yes:启用AOF
redis-cli> config set save "":关闭RDB

参考:Redis数据持久化; Redis作者:深度剖析Redis持久化

using System;
using System.Collections.Generic;
using System.Linq;
using ServiceStack.Redis;
using ServiceStack.Redis.Generic;
namespace RedisHelper
{
public class RedisTool : IDisposable
{
public RedisClient Redis = new RedisClient(“127.0.0.1”, 6379,
“123456”);
//缓存池
private PooledRedisClientManager prcm = new PooledRedisClientManager();

AOF

全持久化形式(日志格局),Append-Only-File,将数据存在内部存款和储蓄器,同时调用fsync将本次写操作命令进行日志记录到aof文件,基于Redis网络交互协议的由Redis标准命令组成的可识别的纯文本文件,只允许扩大不容许改写。

写策略:默许并推举 appendfsync everysec ,速度和安全兼顾。

  • appendfsync always:每提交1个修改命令调用fsync刷新到AOF文件,相当慢、但特别安全;
  • appendfsync everysec:每秒调用fsync刷新到AOF文件,不慢、但大概会丢掉一秒之内的多寡;
  • appendfsync no:依靠OS被动刷新、redis不主动刷新AOF,最快、但安全性差;

AOF最根本的布局就是有关调用fsync追加日志文件持久化数据的频率。磁盘空间满、断电等气象不会潜移默化日志的完整性和可用性。

保存:支持2种方式

  • 调用flushaofbuf,把aof_buf中的命令写入aof文件,再清空aof_buf,进入下二遍loop;

    sds aof_buf; / AOF buffer, written before entering the event loop /

  • aof_rewrite:依据现有的数据库数据反向生成命令,然后把命令写入aof文件中;

加载

fakeClient = createFakeClient();   // 创建伪客户端
while(命令不为空) {
   // 获取一条命令的参数信息 argc, argv
      . . . 
   // 执行
   fakeClient->argc = argc;
   fakeClient->argv = argv;
   cmd->proc(fakeClient);
}

AOF重写

bgrewriteAOF,重新生成一份AOF文件,新的AOF文件只含有对同样个值的累累操作的最终一条记下(能够还原数据的纤维指令集),进度和QashqaiDB类似(Copy-on-Write机制):

  • fork2个子进度,间接遍历旧的AOF文件,将数据写入新的AOF方今文件;
  • 在写新文件进程中,全部的新的写操作日志记录在内部存储器缓冲区中、同时会写入到原来的AOF文件中;
  • 姣好写新文件操作后,发出信号布告父进度将内部存款和储蓄器缓冲区中的写指令3次性追加到一时AOF文件中;
  • 日增完结,Redis将一时AOF文件作为新AOF文件替代旧AOF文件(调用原子性的rename命令用新的AOF文件替代老的AOF文件); 

当同时满意以下1个条件时触发rewrite操作:

auto-aof-rewrite-percentage 100  // 当前写入日志文件的大小占到初始日志文件大小的某个百分比时触发rewrite
auto-aof-rewrite-min-size 64mb   // 本次Rewrite最小的写入数据量

只顾,bgrewriteaof和bgsave无法而且履行,幸免多个Redis后台进程同时对磁盘进行大气的I/O操作。

修复

Redis提供 redis-check-aof.exe 工具扶助日志修复效益:

  • 备份坏的AOF文件;
  • 运行redis-check-aof
    –fix修复坏的AOF文件;
  • 用diff
    -u相比较七个文件的差异,确认难点点;
  • 重启Redis,加载修复后的AOF文件;

public bool Add<T>(string key, T t, int timeout)
{
if (timeout >= 0)
{
if (timeout > 0)
{
secondsTimeOut = timeout;
}
Redis.Expire(key, secondsTimeOut);
}
return Redis.Add(key, t);
}

服务命令

ping:启动服务连接情况
info:查看server/client配置信息
info commandstats + config resetstat:显示/清除名次调用统计信息
config get/set:获取/设置配信息
flushdb/flushall:删除当前所选/所有数据库中的所有key
save/bgsave:数据保存到硬盘/异步保存
lastsave: 上次成功保存到磁盘的unix时间戳
dbsize:查看所有key的数目 
get/set和mget/mset:获取/设置键
incr/decr和incrby/decrby:自增/自减
exists/type key:键key是否存在/键类型
expire key secondTime:设置键的过期时间
rename oldKey newKey:重命名
ttl key:键key的剩余存活时间
select db_index:选择数据库
move key db_index:将键key移动到指定数据库

#endregion

公布订阅机制

publish-subscribe,旁观者模式,订阅者(Subscriber)订阅频道(Channel),发表者(Publisher)将新闻发到内定频道(Channel),通过这种办法将新闻的发送者和接收者解耦,能够实现五个浏览器之间的新闻同步和实时更新。

图片 8

  • 音讯的传递是多对多的;
  • 支持情势匹配;
  • 运行平稳、急忙;

    publish myChannel “xxx”:公布
    subscribe myChannel:订阅
    unsubscribe myChannel:撤销订阅

Redis的Pub/Sub形式允许动态的Subscribe/Unsubscribe,升高系统的布帆无恙和可扩张性。  

/// <summary>
/// 设置缓存
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”key”>缓存建</param>
/// <param name=”t”>缓存值</param>
/// <param
name=”timeout”>过期时间,单位秒,-1:不超时,0:暗中同意过期时刻</param>
/// <returns></returns>
public bool Set<T>(string key, T t, int timeout = 0)
{
if (timeout >= 0)
{
if (timeout > 0)
{
secondsTimeOut = timeout;
}
Redis.Expire(key, secondsTimeOut);
}

RDB

半持久化格局(快速照相方式:File-Snap-Shotting,即时间点转储:Point-in-Time Dump),Redis
DataBase
,将数据先存储在内存,当间接调用save/bgsave命令时或数量修改知足设置的save条件时触发bgsave操作,将内部存款和储蓄器数据2次性写入冠道DB文件。相比符合苦难恢复生机(Disaster
Recovery),若Redis至极crash,方今的数额会丢掉。

rdbcompression yes:创建快照时对数据进行压缩  
dbfilename dump.rdb:快照名称
dir ./saveFile/:快照保存路径(AOF文件存放目录)

原理Copy-on-Write(写时复制)技术

  • Redis forks;
  • 子进度将数据写到暂且中华VDB文件中;
  • 当子进度实现写帕杰罗DB文件,用新文件替换旧文件;

该原理保障别的时候复制景逸SUVDB文件都以相对安全的。

#endregion

布局文件

redis.windows.conf

Redis服务端的运营参数全体靠配置文件贯彻,此处详细介绍Redis配置文件的几个主要参数:

network

  • bind 127.0.0.1:绑定地址(外网连接:0.0.0.0)  
  • port 6379:默许绑定本机的6379端口;
  • timeout:连接超时时间(秒)
  • requirepass pass:配置redis连接认证密码

general

  • loglevel
    debug/notice/warning/verbose:日志级别(开发测试/生产环境/只记录警告错误音信/详细音信)
  • logfile
    ./Logs/redis_log.txt:日志文件保留路径
  • databases 16:数据库数量,暗中同意0

snapshotting

  • save TimeInterval ChangeCnt

append only mode

  • appendonly yes:开启命令日志情势;

limits

  • maxclients 64:最加纳阿克拉接数,0为不限制
  • maxmemory <bytes>:内部存款和储蓄器清理临界值
  • maxmemory-policy
    volatile-lru:内部存款和储蓄器清理选拔的暗中同意策略,对安装过期时间的key实行LRU算法删除

#region Key/Value存储

安装与运用

实际使用:

  • 服务端运行:将指令 redis-server.exe
    redis.windows.conf 写入 .bat 文件,直接运行 StartWithConf.bat 运转服务端;
  • 客户端运转:直接运营 redis-cli.exe 即可;

    redis.windows.conf:配置文件
    redis-benchmark.exe:Redis读写品质测试工具
    redis-check-aof.exe:aof修复检查日志
    redis-check-dump.exe:dump检查数据库文件
    redis-cli.exe:Redis客户端程序
    redis-server.exe:Redis服务器程序
    StartWithConf.bat:运行Redis

/// <summary>
/// 依据lambada表明式删除符合条件的实业
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”listId”></param>
/// <param name=”func”></param>
public void RemoveEntityFromList<T>(string listId, Func<T,
bool> func)
{
using (IRedisTypedClient<T> iredisClient = Redis.As<T>())
{
IRedisList<T> redisList = iredisClient.Lists[listId];
T value = redisList.Where(func).FirstOrDefault();
redisList.RemoveValue(value);
iredisClient.Save();
}
}

基本概念

Redis是名列三甲的NoSQL数据库服务器,其License是Apache
License、完全免费。首先看下内部存款和储蓄器数据库的基本概念:

内部存款和储蓄器数据库

In-Memory DataBase,以内部存款和储蓄器为关键存款和储蓄介质的数目库.

  • 具有的表及索引在内部存款和储蓄器中、化解I/O瓶颈,为访问内部存款和储蓄器设计最佳访问方法和目录形式,读写速度快、质量好;
  • 内存数据库的体积大小受物理内部存款和储蓄器的限量;
  • 安全性难题是硬伤,援救依据政策与磁盘数据库进行多少同步,以及数据库的可信赖性复苏机制;

Redis

REmote DIctionary Server(远程字典服务),远程内部存款和储蓄器数据库(Memory Database + Data Structure
Server),开源的利用ANSI-C语言编写、支持网络、可依据内存亦可持久化的日志型、高质量的key-value数据库,Redis不约定义且不使用表,适应高并发、海量数据存款和储蓄场景。

  • A persistent key-value database with built-in net interface
    written in ANSI-C for Posix systems.
  • Redis is an open source, BSD licensed, advanced key-value cache
    and store.

上边是Redis援救的5种档次数据结构的中间图解(图一):

图片 9

redisObject对象是Redis内部的为主指标,用于表示全数的key和value。

typedef struct redisObject {
    unsigned type:4;  // 数据类型
    unsigned encoding:4;  // 编码方式
    unsigned lru:REDIS_LRU_BITS;   /* lru time (relative to server.lruclock) */
    int refcount;   // 对象的引用计数
    void *ptr;   // 指向真正的存储结构
} robj;

其中,REDIS_LRU_BITS代表当内部存款和储蓄器超过限度时使用LRU算法清除内部存款和储蓄器中的对象。redisObject对象的创办在object.c文件中:

robj *createObject(int type, void *ptr) {
    robj *o = zmalloc(sizeof(*o));
    o->type = type;
    o->encoding = OBJ_ENCODING_RAW;
    o->ptr = ptr;
    o->refcount = 1;

    /* Set the LRU to the current lruclock (minutes resolution). */
    o->lru = LRU_CLOCK();
    return o;
}    

Redis的键类型为string,值类型帮忙:

  •  字符串:string
  •  列表:list
  •  集合:set
  •  有序集合:zset (SortedSet)
  •  散列:hash

切实内部存款和储蓄器结构示意图(图二):

图片 10

参考:Redis数据库入门教程; Redis学习笔记

特点

  • 全总数量In-Momory,作为Memcached的替代者;
  • key-value存款和储蓄系统(Key:数据检索的绝无仅有标识、Value:数据存款和储蓄的关键对象),协理八种类型的value(数据结构服务器);
  • redis的源点是cache,缓存,高速缓存;
  • 数码存款和储蓄于内部存款和储蓄器中或被布置为利用虚拟内部存储器;
  • 持久化天性(Persistence):能够持久化到磁盘(周期性把创新数据写入磁盘或把修改操作追加写入记录文件);
  • 主从复制天性(Master/Slave
    Replication):负载均衡,扩张读质量;
  • 客户端分片(Client-Side
    Sharding):数据划分为八个部分,扩充写质量,线性级其余性质升高;
  • 支撑种种不一样措施的排序;
  • 支撑简单的事务(仅达成一遍性执行多条命令的效果,不帮忙回滚);
  • 支撑设置数据过期时间;

内存优化

  • string和数字:Redis内部维护3个数字池,能够省去存款和储蓄空间,暗许 REDIS_SHARED_INTEGERS = 10000 
  • 复杂类型的贮存优化:Redis内部使用紧密格式存款和储蓄数据(适合集合包蕴的Entry不多并且各个Entry包涵的Value不是不长的动静),遍历复杂度降低为O(n)、但节省存款和储蓄空间。以ZIPMap的数据结构为例:

  图片 11

 
在那之中,字段free用于冗余空间,空间换时间、一定景况下幸免插入操作引起的扩大体量操作。

  • list、set、hash接纳十一分规编码,优化存款和储蓄空间;
  • byte、bit级其他操作:getrange/setrange、getbit/setbit以及bitmap高效存款和储蓄;

Redis .vs.
Memcached

  • 二者均是高质量键值缓存服务器,Memcached只提供数据缓存服务,Redis提供数据缓存和持久化;
  • Memcached:二十八线程服务器;Redis:单线程服务器,部分质量通过二十四线程落成;
  • Memcached只扶助一般字符串键;Redis提供丰裕的数据存储结构,同时辅助主数据库(Primary
    Database)+ 辅助数据库(Auxiliary Database)使用;
  • Memcached:预分配内部存储器池格局,Redis:现场报名内部存款和储蓄器的方法存款和储蓄数据、且能够计划虚拟内部存款和储蓄器

/// <summary>
/// 添加单个实体到链表中
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”listId”></param>
/// <param name=”Item”></param>
/// <param name=”timeout”></param>
public void AddEntityToList<T>(string listId, T Item, int timeout
= 0)
{
IRedisTypedClient<T> iredisClient = Redis.As<T>();
if (timeout >= 0)
{
if (timeout > 0)
{
secondsTimeOut = timeout;
}
Redis.Expire(listId, secondsTimeOut);
}
IRedisList<T> redisList = iredisClient.Lists[listId];
redisList.Add(Item);
iredisClient.Save();
}

主导机制

master-slave,为了升高持久化学工业机械制,在持久化基础上Redis提供复制作用:将3个主服务器(master)数据自动同步到多个从服务器(slave),实现中央同步:

  • 纯粹的冗余备份
  • 晋升读质量

具体地:

  • 运营从服务器,先向主服务器发送SYNC命令;
  • 主服务器收到SYNC命令后fork子进程始起保存快速照相,时期全体发给主服务器的指令都会被缓存到内部存款和储蓄器;
  • 快速照相保存完毕后,主服务器把快速照相和缓存的一声令下全体发送给从服务器;

  • 从服务器保存收到的快速照相文件并加载到内部存款和储蓄器中,然后挨家挨户执行收到的缓存命令;

在着力同步进度中(异步完结),从服务器不会堵塞,时期暗中认可使用同步在此之前的数码继续响应客户端命令。主从机制帮衬增量同步策略,降低连接断开的死灰复燃资本。

实际使用中国和东瀛常是:Redis+MySQL

图片 12

/// <summary>
/// 获取
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”key”></param>
/// <returns></returns>
public T Get<T>(string key)
{
return Redis.Get<T>(key);
}

其他

排序

问题:数据库帮助排序,为何要把排序功用放在缓存中达成?

  • 排序会追加数据库的载荷,难以支撑高并发的行使;
  • 在缓存中排序不会赶上表锁定的题材;

    sort key [BY pattern] [LIMIT offset cnt] [GET pattern [GET pattern …]] [asc | desc] [ALPHA] [STORE destination]

  • by:即order by,内定排序字段,by
    *->子键名;

  • limit:限制排序后回来成分的数量,表示跳过前offset个因素、再次来到之后的连接cnt个要素,能够完结分页作用;
  • get:重临钦赐的字段值,get
    *->子键名;
  • store:将排序结果存入钦赐地方;  

事务

Transaction。

  • multi:原子操作,通知Redis,接下去的多少下令属于同一业务;
  • 输入若干指令,存款和储蓄在命令队列中而不会被当即实施;
  • exec:原子操作,文告Redis,属于同一业务的有所命令输入完毕,最西施行工作;

管道

pipilining,允许Redis1遍性接收多个指令、执行后二次性再次回到结果,减弱客户端与Redis服务器的通讯次数、降低往返时延。类似事情,通过原子操作multi/exec实现。

先期级队列

blpop/brpop。

/// <summary>
/// 依据IEnumerable数据添加链表
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”listId”></param>
/// <param name=”values”></param>
/// <param name=”timeout”></param>
public void AddList<T>(string listId, IEnumerable<T> values,
int timeout = 0)
{
Redis.Expire(listId, 60);
IRedisTypedClient<T> iredisClient = Redis.As<T>();
if (timeout >= 0)
{
if (timeout > 0)
{
secondsTimeOut = timeout;
}
Redis.Expire(listId, secondsTimeOut);
}
IRedisList<T> redisList = iredisClient.Lists[listId];
redisList.AddRange(values);
iredisClient.Save();
}

//释放能源
public void Dispose()
{
if (Redis != null)
{
Redis.Dispose();
Redis = null;
}
GC.Collect();
}

/// <summary>
/// 缓冲池
/// </summary>
/// <param name=”readWriteHosts”></param>
/// <param name=”readOnlyHosts”></param>
/// <returns></returns>
public static PooledRedisClientManager CreateManager(
string[] readWriteHosts, string[] readOnlyHosts)
{
return new PooledRedisClientManager(readWriteHosts, readOnlyHosts,
new RedisClientManagerConfig
{
MaxWritePoolSize = readWriteHosts.Length * 5,
MaxReadPoolSize = readOnlyHosts.Length * 5,
AutoStart = true,
});
// { RedisClientFactory =
(IRedisClientFactory)RedisCacheClientFactory.Instance.CreateRedisClient(“127.0.0.1”,
6379) };
}
}

/// <summary>
/// 删除
/// </summary>
/// <param name=”key”></param>
/// <returns></returns>
public bool Remove(string key)
{
return Redis.Remove(key);
}

/// <summary>
/// 获取链表
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”listId”></param>
/// <returns></returns>
public IEnumerable<T> GetList<T>(string listId)
{
IRedisTypedClient<T> iredisClient = Redis.As<T>();
return iredisClient.Lists[listId];
}

}

#region 清空Redis全体数据库中的全数key
public void Flushall()
{
Redis.FlushAll();
}
#endregion

/// <summary>
/// 在链表中删除单个实体
/// </summary>
/// <typeparam name=”T”></typeparam>
/// <param name=”listId”></param>
/// <param name=”t”></param>
public void RemoveEntityFromList<T>(string listId, T t)
{
IRedisTypedClient<T> iredisClient = Redis.As<T>();
IRedisList<T> redisList = iredisClient.Lists[listId];
redisList.RemoveValue(t);
iredisClient.Save();
}

return Redis.Add(key, t);
}

相关文章