几分钟搞定redis存储session共享——设计实现

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 几分钟搞定redis存储session共享——设计实现

前面我们写过C#在redis中存储常用的5种数据类型demo,没看过的可以点击电梯直达:https://www.cnblogs.com/xiongze520/p/10267804.html

我们上一篇说到Windows7系统中使用nginx部署服务器集群:https://www.cnblogs.com/xiongze520/p/10308720.html

部署完成后我们对于session的共享没有完成,之前小编想做一个session服务器做共享,然后看到评论AjuPrince三当家的方法,我决定使用第三方缓存(redis)

解决session共享问题。通过查询资料整理如下设计:


  • Session的实现原理
  • Session共享实现
  • Redis存储session的需要考虑问题
  • demo演示

Session的实现原理:

  1. 服务端首先查找对应的cookie的值(sessionid)。
  2. 根据sessionid,从服务器端session存储中获取对应id的session数据,进行返回。
  3. 如果找不到sessionid,服务器端就创建session,生成sessionid对应的cookie,写入到响应头中。

Session共享实现:

传统的session由服务器端生成并存储,当应用进行分布式集群部署的时候,如何保证不同服务器上session信息能够共享呢?

两种实现方式:

  1. session集中存储(redis,memcached,hbase等)。
  2. 不同服务器上session数据进行复制,两种方式的优缺点,大家应该一目了然。

基于session集中存储的实现方案:

  • 新增Filter,拦截请求,包装HttpServletRequest
  • 改写getSession方法,从session存储中获取session数据,返回自定义的HttpSession实现
  • 在生成新Session后,写入sessionid到cookie中

Redis存储session的需要考虑问题:

  1. session数据如何在Redis中存储?
  2. session属性变更何时触发存储?

实现:

考虑到session中数据类似map的结构,采用redis中hash存储session数据比较合适,如果使用单个value存储session数据,不加锁的情况下,就会存在session覆盖的问题,因此使用hash存储session,每次只保存本次变更session属性的数据,避免了锁处理,性能更好。

如果每改一个session的属性就触发存储,在变更较多session属性时会触发多次redis写操作,对性能也会有影响,我们是在每次请求处理完后,做一次session的写入,并且之写入变更过的属性。

如果本次没有做session的更改, 是不会做redis写入的,仅当没有变更的session超过一个时间阀值(不变更session刷新过期时间的阀值),就会触发session保存,以便session能够延长有效期。


demo演示:

我们还是使用上传的demo进行稍加修改:

不用说,我们首先启动redis,不知道的可以点击电梯直达:https://www.cnblogs.com/xiongze520/p/10267804.html

然后代码如下:

using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace RedisApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //建立Redis客户端类,构造函数(安装Redis服务器的服务器ip,端口号)
            RedisClient client = new RedisClient("192.168.0.43", 6379);  //链接Redis服务器
            client.FlushAll();  //命令用于清空整个Redis服务器的数据(删除所有数据库的所有密钥)。
            //-----------------将数据存入Redis-----------------
            //SetEntryInHash(hashid,key,value) hashid是唯一标识符
            client.SetEntryInHash("HashID", "Name", "张三");
            client.SetEntryInHash("HashID", "Age", "24");
            client.SetEntryInHash("HashID", "Sex", "男");
            client.SetEntryInHash("HashID", "Address", "上海市XX号XX室");
            client.SetEntryInHash("HashID2", "Name", "张三");
            client.SetEntryInHash("HashID2", "Age", "24");
            client.SetEntryInHash("HashID2", "Sex", "男");
            client.SetEntryInHash("HashID2", "Address", "上海市XX号XX室");
            //-----------------读取存入的数据-----------------
            List<string> HaskKey = client.GetHashKeys("HashID");
            foreach (string key in HaskKey)
            {
                Console.WriteLine("HashID--Key:{0}", key);
            }
            List<string> HaskKey2 = client.GetHashKeys("HashID2");
            foreach (string key in HaskKey2)
            {
                Console.WriteLine("HashID2--Key:{0}", key);
            }
            //-----------------删除对象-----------------
            //client.RemoveEntryFromHash("HashID", "Name");
        }
    }
}

我们获取指定的key,运行效果图如下:

 

这样就完成redis存储和session共享的问题了,避免iis的session不共享和覆盖问题。

再次感谢AjuPrince三当家的思路。

有不同的解决方案可以在评论区套路套路。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
98 1
|
2月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
52 2
数据的存储--Redis缓存存储(二)
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
78 6
|
4月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
1月前
|
存储 NoSQL 算法
Redis分片集群中数据是怎么存储和读取的 ?
Redis集群采用哈希槽分区算法,共有16384个哈希槽,每个槽分配到不同的Redis节点上。数据操作时,通过CRC16算法对key计算并取模,确定其所属的槽和对应的节点,从而实现高效的数据存取。
47 13
|
1月前
|
存储 NoSQL Redis
【赵渝强老师】Redis的存储结构
Redis 默认配置包含 16 个数据库,通过 `databases` 参数设置。每个数据库编号从 0 开始,默认连接 0 号数据库,可通过 `SELECT &lt;dbid&gt;` 切换。Redis 的核心存储结构包括 `dict`、`expires` 等字段,用于处理键值和过期行为。添加键时需指定数据库信息。视频讲解和代码示例详见内容。
|
2月前
|
NoSQL Redis API
限流+共享session redis实现
【10月更文挑战第7天】
41 0
|
3月前
|
存储 NoSQL Redis
2)Redis 的键值对长什么样子,又是怎么存储的?
2)Redis 的键值对长什么样子,又是怎么存储的?
47 0
|
4月前
|
存储 消息中间件 NoSQL
Redis命令详解以及存储原理
Redis命令详解以及存储原理
|
4月前
|
存储 NoSQL Redis
Redis存储原理与数据模型
Redis存储原理与数据模型