设为首页 收藏本站
查看: 1142|回复: 0

[经验分享] 使用redisco轻松将python内置数据类型存入redis内

[复制链接]

尚未签到

发表于 2016-12-21 08:38:42 | 显示全部楼层 |阅读模式
  我在之前的 <
python使用redis 神器 ---redisco(一)>中已经简单介绍了redisco这个python的redis库的特点。

  接下来这篇文章想着重分享一下如何将python内置的数据类型通过redisco存储到redis内,实现方便的存取和原子化操作,而不用去关心存储在redis里的数据会因为多进程(线程)需要添加“锁”这种繁琐的操作。
  

  我先讲下我当时遇到的麻烦把,公司项目中的游戏服务器在一开始开发的时候都是以单进程来调试开发的,当我们在开发一些类似于副本或者战场之类功能的时候不得不在程序内生成以为所谓的“战场”或者“副本”的数据结构来存储数据,并给在参加这些战斗的玩家共享数据。那么一般在python内部会用一个class或者dict来设计这些数据结构。
  

  当然在单进程的情况下没有问题,因为这些数据都是在内存里交互。但是当服务器架构被改造成多进程后,不同的玩家会随机的连接在服务器的各个进程上,那么他们就不能像之前很方便的共享单进程时里这些战场的数据。
  一般在今天要解决多进程数据共享也不是什么很复杂的问题了,无非是用缓存,RPC调用等等。
  

  但是这些方法都不能很方便的解决将之前用python生成的数据结构数据进行方便的存储和读取,一般会进行一次编码和解码,比如都转成json,或者二进制,效率不高而且繁琐,最恶心的关键数据比如比分,金钱,这些在不同的进行需要进行更改时要加锁,这样性能又会下降,想想就恶心。
  

  

  好了,终于可以让我们的redisco出场了,长话短说,我们来看看用它来存储python数据如何方便。
  

  python                 redisco
  =========================
  字典,类                models.Model
  列表                      list
  字符串,数字          key,value对
  

  

  上面这张表是python内数据对应到redisco内数据结构的映射
  

  主要讲下当你在使用redisco中models.Model用来替代python内部的字典和类时的注意事项
  

  

  在models.Model中当你生成了一个数据调用save方法存入redis后比如这样写的

Python代码 
  DSC0000.png





  • from redisco import models  
  • class Person(models.Model):  
  •     name = models.Attribute(required=True)  
  •     created_at = models.DateTimeField(auto_now_add=True)  
  •     fave_colors = models.ListField(str)  
  •     age = models.Counter()

  •     score = 
    models.IntegerField()
  在你的进程内生成一个数据

test  = Person()
test.name = 'xiaoming'
test.save() #存进redis
如果你不销毁test变量,那么可以一直直接访问它的属性
比如
>>print test.name
>>xiaoming
>>print test.age
>>0
修改score属性
>>test.score = 1
>>test.save()#跟新redis内数据
修改age
>>test.incr('age',5)
>>print test.age
>>5
   注意区别同样是数字 redisco 内 Counter 和 
IntegerField 一个不需要调用save方法一个需要

  ==========================
  那么神奇的地方仅仅只有这点????
  

  

  如果此时有个b进程也在修改test这个数据
  

  会怎么样?
  

  我直接告诉你结果吧
  

  如果你要正确的修改test的score
  

  在每次修改前都需要重新获取一次test数据
  

  而修改age则不用,你只要调用test的incr() 和decr() 就可以修改 
  

  将简单点,在a进程和b进程同事通过 Person.objects.filter(name='tset')[0] 获取了叫‘test’名字的这个人的数据
  

  然后a,b2个进程同时使用 test.incr('age')
  

  再print test.age你会发现增加了2 而不是增加了1
  对于list类型和zset类型在之前的文章已经提过就不细说了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-317126-1-1.html 上篇帖子: 基于Redis的ASP.NET与js(AJAX)的聊天程序 下篇帖子: Redis实践:使用Pub/Sub实现对服务器群的管理监控
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表