Redis基础(转)

ServiceStack.Redis实践

Redis的C#客户端我选择的是ServiceStack.Redis,相比Booksleeve redis-sharp等方案,它提供了一整套从 Redis数据结构都强类型对象转换的机制;看一个例子来了解一下ServiceStack.Redis是如何组织数据的,我们使用的实体类定义如下:

?


1

2

3

4

5

6

7

8

9

10

11

public class User

   {

       public User()

       {

           this.BlogIds = new List<long>();

       }

       public long Id { get; set; }

       public string Name { get; set; }

       public List<long> BlogIds { get; set; }

   }</long></long>

使用下面的代码片段,我们存入两条数据到Redis:

?


1

2

3

4

5

6

7

using (var redisUsers = redisClient.GetTypedClient<user>())

        {

            var ayende = new User { Id = redisUsers.GetNextSequence(), Name = "Oren Eini" };

            var mythz = new User { Id = redisUsers.GetNextSequence(), Name = "Demis Bellot" };

            redisUsers.Store(ayende);

            redisUsers.Store(mythz);

          }</user>

我们看下Redis中的结果:

?


1

2

3

4

5

redis 127.0.0.1:6379[1]> keys *

1) "seq:User"

2) "ids:User"

3) "urn:user:1"

4) "urn:user:2"

我们逐一检查一下数据类型:


 seq:User    

string  

维护当前类型User的ID自增序列,用做对象唯一ID

 ids:User

set       

同一类型User所有对象ID的列表

 urn:user:1

string 

user对象

seq:User 维护的是类型User的ID序列 redisUsers.GetNextSequence()

?


1

2

3

4

5

6

7

8

public long GetNextSequence(int incrBy)

  {

             return IncrementValueBy(SequenceKey, incrBy);

  }

 public long IncrementValue(string key)

    {

              return client.Incr(key);

     }

这里的SequenceKey就是 "seq:User",然后我们通过存一个对象到Redis看另外两个key是什么作用:

?


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

public T Store(T entity)

       {

           var urnKey = entity.CreateUrn();

           this.SetEntry(urnKey, entity);

           return entity;

       }

       //entity.CreateUrn();的结果是"urn:user:1"

       public void SetEntry(string key, T value)

       {

           if (key == null)

               throw new ArgumentNullException("key");

           client.Set(key, SerializeValue(value));

           client.RegisterTypeId(value);

       }

       internal void RegisterTypeId<t>(T value)

       {

           var typeIdsSetKey = GetTypeIdsSetKey<t>();

           var id = value.GetId().ToString();

           if (this.Pipeline != null)

           {

               var registeredTypeIdsWithinPipeline = GetRegisteredTypeIdsWithinPipeline(typeIdsSetKey);

               registeredTypeIdsWithinPipeline.Add(id);

           }

           else

           {

               this.AddItemToSet(typeIdsSetKey, id);

           }

       }</t></t>

这里的typedIdsSetKey 就是"ids:User"

ids:User相当于一个索引,包含了所有同为类型User的ID;由于维护了这样一个分组信息,所以很容易实现GetAll()这样的功能;

在redis-cli中查询一下 get urn:user:1 返回值是 JSON格式:

"{\"Id\":1,\"Name\":\"Oren Eini\",\"BlogIds\":[1]}"

ServiceStack.Redis 自己实现了一套序列化功能, Fastest JSON Serializer for .NET released 支持 POCO(Plain Old CLR Object)序列化.

实际应用中,由于我们使用的数据是来自关系型数据库,本身包含关联关系,所以并不需要这样的对象组织方式;我们只需要把关系型数据中一对多的关系在Redis中表达出来即可;这里我扩展修改了RedisClient的实现,由于RedisClient本身已经通过 partial方式 分割成若干个文件,所以很容易把变动的代码集中在同一个代码文件中.具体业务对象存储,主帖和回帖会有字段级修改,所以设计成为Hash结构,其它几个子对象读写都是以对象为单位,设计成为POCO方式持久化;

使用管道Pipeline遇到的问题

使用管道可以将客户端到Redis的往返次数减少,不过在使用ServiceStack.Redis的时候,遇到这样一个问题,比如要把一个List全部存储,代码不可以写成下面这样:

?


1

2

3

4

5

6

7

8

9

%%第一种写法

           logs.ForEach(n =>

                {

                    pipeline.QueueCommand(r =>

                    {

                        ((RedisClient)r).Store<oplog>(n, n.GetObjectID(), n.GetUrnKey());

                        ((RedisClient)r).Expire(n.GetUrnKey(), dataLifeTime);

                    });

                });</oplog>

而是要写成这样:

?


1

2

3

4

5

6

7

8

%%第二种写法

 logs.ForEach(n =>

                {

  

                    pipeline.QueueCommand(r => ((RedisClient)r).Store<log>(n, n.ID, n.GetUrnKey()));

                    pipeline.QueueCommand(r => ((RedisClient)r).Expire(n.GetUrnKey(), dataLifeTime));

                });</log>

什么原因呢?RedisQueueCompletableOperation的AddCurrentQueuedOperation方法会在
执行CurrentQueuedOperation =
null;如果按照第一种写法会丢失回调函数,这就造成有返回值在没有及时提取,后续的操作获取返回值时首先取到的是积压的结果信息,就出现了异常,而第
二种写法就避免了这个问题.

?


1

2

3

4

5

protected virtual void AddCurrentQueuedOperation()

      {

          this.QueuedCommands.Add(CurrentQueuedOperation);

          CurrentQueuedOperation = null;

      }

时间: 2024-10-03 07:38:52

Redis基础(转)的相关文章

REDIS基础笔记

Redis基础笔记 资源链接 简介 简介 安装 五种数据类型及相应命令 1. 字符串类型 2. 散列类型 3. 列表类型 4. 集合类型 5. 有序集合 其他 事务 SORT 生存时间 任务队列 发布/订阅模式 Python中使用Redis 实际实例 管理 其他 资源链接 推荐书籍:<Redis入门指南> 资源列表: redis命令速查command | CMD索引-中文 | CMD树-中文 redis源码github 下载地址redis.io The Little Redis book 入口

linux redis基础应用 主从服务器配置

Redis基础应用 redis是一个开源的可基于内存可持久化的日志型,key-value数据库redis的存储分为内存存储,磁盘存储和log文件三部分配置文件中有三个参数对其进行配置 优势:和memcached相比,它支持存储的value类型相对更多,包括strings,lists,zsets(sorted set)和hashesredis会周期性的吧更新的数据写入磁盘或者把修改操作写入追加的记录文件并且在此基础上实现了master-slave(主从)同步 redis服务器服务器程序:redis

Redis 基础应用

Redis 基础应用(一) ============================================================================== 概述: ============================================================================== Redis简介  1.简介 ★Redis REmote DIctionary Server(Redis) 是一个由Salvatore Sanfili

初学者必须掌握的redis 基础

这篇文章总结了常用的redis基础知识,希望初学者能够从中受益. 一 redis数据类型 redis支持5种类型的数据类型,它描述如下的: 1. 字符串 Redis字符串是字节序列.Redis字符串是二进制安全的,这意味着他们有一个已知的长度没有任何特殊字符终止,所以你可以存储任何东西,512兆为上限. 2. 哈希 Redis的哈希是键值对的集合. Redis的哈希值是字符串字段和字符串值之间的映射,因此它们被用来表示对象. 3. 列表 Redis的列表是简单的字符串列表,排序插入顺序.您可以添

Redis 基础操作

[Redis 基础操作] 1.ECHO message. Returns message. 2.PHING Returns PONG if no argument is provided, otherwise return a copy of the argument as a bulk. This command is often used to test if a connection is still alive, or to measure latency. 3.SELECT index

redis 基础数据结构实现

参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己的底层数据结构:动态字符,双端链表,字典,压缩列表,整数集合和跳跃表等.通过这些数据结构,redis构造出字符串对象,列表对象,哈希对象,集合对象和有序集合对象这5种我们常用的数据结构.接下来将从底层数据结构开始,一步步介绍redis的数据结构的实现 动态字符串 在redis中并没有使用c语言原生的

mysql主从复制、redis基础、持久化和主从复制

一.mysql(mariadb)基础 1.基础命令(centos7操作系统下) 1.启动mysql systemctl start mariadb 2.linux客户端连接自己 mysql -uroot -p -h 127.0.0.1 -u 用户 -p 密码验证 -h 连接的主机地址 3.远程链接mysql服务端 mysql -uroot -p -h 192.168.3.115 4.修改mysql密码 # 修改当前用户的密码 set password = PASSWORD('mariadb123

一文了解:Redis基础类型

一文了解:Redis基础类型 Redis特点 开源的,BSD许可高级的key-value存储系统 可以用来存储字符串,哈希结构,链表,集合 安装 windows:https://github.com/microsoftarchive/redis/releases mac\linux:http://www.redis.cn/ Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(有序集合). string(字符串)

redis基础及配置文件详解

一.redis部署与使用 redis 基础 官网地址https://redis.io/ Redis和 Memcached 是非关系型数据库,也称为NoSQL数据库 ,MySQL . Mariadb . SQL S erver . PostgreSQL .Oracle 数据库 属于关系型数据 RDBMS, Relational Database Management System redis 简介 Redis (Remote Dictionary S erver 在 2009 年 发布 开发者 S

2.【Redis系列】Redis基础数据结构

原文:2.[Redis系列]Redis基础数据结构 千里之行始于足下,我们先来看看redis的基础知识. Redis有5中基本数据类型:字符串(string).列表(list).集合(set).有序集合(zset).字典(hash).熟练掌握这5种基本数据结构也是最基本最重要的部分. String(字符串) 字符串是redis中最简单的数据结构,Redis所有的数据结构都是以唯一key作为名称,然后通过唯一的key来获取相应的redis数据.不同类型的数据结构的差异就在于value的结构不一样.