服务器与客户端的数据同步

问题

  • 从一个例子说起,我们的客户端从服务器获取数据,这里假定获取文章。第一次使用,我们获取服务器端最新发表的几篇文章。
  • 我们可以每次都重新获取,但这样费时又费流量。好的设计应该是我们把获取过的文章存下来,下次只获取最新发表的文章。
    
  • 这样就有个问题,如果某一篇文章,我们已经获取过了,可有一天它更新了。。。。
    
  • 还有个问题,文章持续获取下去,我们手机没空间了。。。。
  • 如何使我们客户端能保存有限的文章,并且同时可以得到更新呢?
    

解决方法

  • 为了保证客户端不存过多文章,我们应该设置一个过期期限,当缓存的文章比较老旧,删除掉即可。
  • 为了保证客户端的文章能够得到更新,服务器的文章表应该有个最后修改时间字段。同时服务器端保存客户端最后一次获取文章的时间,保存在session里。
    

1、文章表设计

  • | index | content | ts | dl |
  • index 索引;
  • content 内容;
  • ts 文章最后一次的修改时间。把ts的格式设计为:NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,即默认为当前的时间戳,且随着文章更改,自动更新为更改时间。
  • dl 文章是否被删除了;

2、客户端查询文章时服务器端的工作

  1. 从session中查询该用户对文章的最后一次获取时间,last_gotten_ts;
  2. 如果有该记录,说明只需要给客户端发送last_gotten_ts只后的文章(dl != 1 AND ts > last_gotten_ts);
  3. 如果没有该记录,表示是这个用户第一次获取,那发送最近的若干条文章(dl != 1 ORDER BY index DESC LIMIT 10)。
  4. 将session里的last_gotten_ts设置为结果集里最大的ts.

3、客户端查询到最新文章时的工作

  1. 根据接收到的文章,新增或更新本地缓存。这里使用REPLACE INTO更合适。同时,根据dl字段判断是否已经被删除,如果是,删除本地的文章;
  2. 删除过期的缓存文章;
  3. 展示文章列表,注意这里应该以index,而不是ts排序。这样保证文章是以创建时间排序,而非更新时间。

4、向前查询

  1. 这种情况适用于上拉列表时加载更多文章的功能。目标是获取某个文章之前的文章。因此客户端请求时,应该带着最后一条文章的index,服务器返回该index之前的若干文章。注意这时候,不应该存储last_gotten_ts。

5、为什么将last_gotten_ts存到session而不是数据库

  1. 我们也可以新建一个表。类似这样的结构: | user_index | last_gotten_ts | 但是这样会有如下两个问题:
  2. 用户在其它设备登录了,这时候服务器会以为是从老设备上请求的,只发送last_gotten_ts后的文章,导致两个设备相互干扰。
  3. 当客户端好长时间没有使用时,可能导致服务器这段时间累积的文章量比较大。而事实上当客户端再次使用时,客户端没必要全部接受,只需要接收最新的若干文章(就像第一次使用时那样)。
  4. 使用session则可以巧妙解决这两个问题。
  5. 两个设备相互干扰,显然不是我们希望的。而session是跟设备相关的,在服务器端每个设备有自己的session,这样的话相当于每个设备都相互独立,可以巧妙避开干扰。
  6. 如果我们把session的过期时间设置恰当,当客户端再次使用时,旧session已经过期。新的session里并没有任何查询历史。正如客户端第一次使用那样。这样就完美地解决了服务器端文章累积的问题。

6、客户端的文章“断层”

  1. 当客户端长时间不用,后面再使用时,因为没有全部获取,可能导致与缓存的老文章之间不连续,有“断层”。这样的话,如果用户再想加载更多文章时,可能我们的代码会跳过这个断层,直接加载老文章之前的文章。这样的话这个“断层”就没机会获取到了,丢失了。
  2. 如何解决这个问题呢?其实很简单,只要设置好客户端本地的过期期限即可。客户端每次启动,都检查是不是有缓存文章过期了,如果过期了,就删除之。很明显,这个时间期限不能大于服务器端的session的过期时间。

7、服务器端的文章的dl字段

  1. 这个字段既然是删除的意思,那为什么不直接删除该记录呢?这个字段的实质目的,是要告诉客户端该记录被删除了。如果直接删除了该记录,客户端无从得知这个删除信息,那本地的缓存也就无法删掉。
  2. 如果已经被删了,还留在表里,是不是不太好?的确不好。服务器定期检查这些被删记录的删除时间(ts),如果超过一定期限了,那也删除之。注意这个期限不能小于客户端缓存的时间,即:保证在客户端删除了本地缓存记录之后,再删除该记录。

转载于:https://my.oschina.net/jiaozebo/blog/600010

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值