会话(session)管理是互联网应用的重要功能,当业务在多地部署时,会话管理就有了就近访问和多地容灾的需求,云数据库Redis版可以帮助业务实现高效的会话管理。

背景信息

随着业务规模不断扩大,应用的使用者可能需要在不同的地域使用服务,此时通常需要采用多地容灾架构来部署应用,这样既可以实现就近服务,从而提高用户的访问速度,又能在服务发生单地故障时,通过异地容灾快速恢复正常服务,提高可用性和可靠性。

为了使用户获得较好的跨地域使用体验,应用的会话管理功能同样需要具备多地容灾能力,以下两个场景展示了具有多地容灾会话管理功能的应用给用户带来的优质体验。

  • 用户场景一

    用户A在上海注册并登录某应用后,出差到了北京。因为该应用的会话管理功能是异地容灾部署的,用户A在北京尝试使用其服务时,不需要重新登录。

  • 用户场景二

    上海用户B最近经常使用某应用,感觉一直很稳定。实际上,该应用在上海地域的会话管理服务器曾在几天前出现过一次故障,期间,应用从北京地域的服务器获取到了其会话信息,因此用户B的使用体验没有受到影响。

下文基于一个案例对如何使用Redis实现多地容灾的会话管理进行了详细说明。

业务案例

  • 需求
    • 因用户遍布全国,部署应用服务的地域需要间隔稍远,尽量使全国各地用户在访问业务时都能获得较理想的访问速度。
    • 如果应用服务发生单地故障,尽量不要影响用户的会话,因此需要在多地间同步数据,保持全局会话信息一致。

结合以上需求分析结果制定的业务方案如下:

  • 地域选择

    选择上海、北京、河源三个阿里云服务地域,分别覆盖华东区域、华北区域和华南区域,这样也能较好地兼顾其它区域。在这三个地域分别创建云数据库Redis版实例

  • 数据同步

    在业务层实现地域间的数据同步,其优势如下:

    • 灵活性强,可以根据业务中数据的时效性决定采用同步还是异步的方式同步数据。
    • 在进行读操作时,可以通过补偿回写机制避免额外的写同步操作,详情请参见下文的写操作说明。

    具体实现方案请参见下方的写操作和读操作说明。

  • 写操作

    当用户在某地创建会话时,应用异步地将数据推送到其它两个地域,其架构图和示例代码如下。

    会话容灾服务架构1
    IF (OK == Redis_SH-> Set (sessionid, sessionInfo, 600))
        Redis_BJ-> Set(sessionid, sessionInfo, 600)
        Redis_HY-> Set(sessionid, sessionInfo, 600)
  • 读操作

    如果用户获取会话信息的请求因某种原因被发送到了异地的Redis实例,例如上海用户的请求发送到了北京,则优先从当地(北京)的Redis实例读取数据。如果在北京的Redis实例中没有查询到所请求的数据,则返回源地域(上海)的Redis实例中读取数据,然后再将该数据写回到北京的实例。架构图和示例代码如下。

    会话容灾服务架构2
    IF (localIp match Heyuan)
       sessionInfo = Redis_HY-> GET(sessionid)
       IF sessionInfo == NULL
       sessionInfo = Redis_SH-> GET(sessionid)
  • 会话信息结构

    为了区分用户写入会话的区域,sessionid生成后,应用会替换其第一个字符。例如,从上海写入的sessionid,其首字母会被替换为s,北京则为b,河源则为h。通过这种方法,应用就能够判断会话源自于哪个地域。

    在sessionid的有效期内,如果上海(源地域)的用户在北京发起了请求,应用会将更新的数据同步地写入用户当前所在地域(北京)和源地域(上海)的Redis实例,再异步写入其它地域(河源)的Redis实例,以这样的方式保证sessionid与其对应信息的一致性。

案例总结

本文介绍的使用Redis实现多地容灾会话管理的方案,不依赖于Redis产品的异地数据同步功能,而是通过业务层实现,具备更好的灵活性,可以满足更多大规模应用的服务需求。