基于python+mysql浅谈redis缓存设计与数据库关联数据处理

by:授客  QQ:1033553122

测试环境

redis-3.0.7

CentOS 6.5-x86_64

python 3.3.2

基于Python操作Redis

  1. 1创建示例数据库表
  1. CREATE TABLE tb_signin_rank(
  1. id INT,
  1. user_name VARCHAR(10) COMMENT '用户名',
  1. signin_num INT COMMENT '签到次数',
  1. signin_time DATETIME COMMENT '签到时间',
  1. gold_coin INT COMMENT '金币'
  1. );
  1.  
  1. 初始化数据
  1. INSERT INTO tb_signin_rank
  1. VALUES(1, 'shouke', 0, NULL, 0),
  1. (2, 'chuangke', 0, NULL, 0),
  1. (3, 'ishouke', 0, NULL, 0),
  1. (4, 'keshou', 0, NULL, 0),
  1. (5, 'shouke', 0, NULL, 0);
  1.  
  1.  
  1. 2redis缓存键值设计
  1. key               value
  1. 表名:主键值:列名   列值
  1.  
  1. 或者如下,通过为不同列之间建立较为紧密的关联
  1. key                        value
  1. 表名:主键值:列值1:列名2   列值2
  1.  
  1.  
  1.  
  1. 示例:把id1的人的签到次数(假设为5)存储到redis中则可如下操作:
  1. set('tb_signin_rank:1:signin_num', 5)
  1.  
  1. 这样做的好处是,类似数据库一样,通过主键便可获取其它值。
  1.  
  1. 示例:把id和用户名关联
  1. set('tb_signin_rank:shouke:id', 1)
  1.  
  1. 这样,通过用户名就可以查询出关联的id了:uid = r.get("tb_signin_rank:%s:id" % username)
  1.  
  1.  
  1. 3redis关联数据库的数据处理
  1.  
  1. 不要求强一致实时性的读请求,都由redis处理
  1. 要求强一致实时性的读请求,由数据库处理
  1. 通常包含以下两种处理模式:
  1. 模式1
  1. 如图,先判断是否存在缓存(通常是根据key),如果存在则从缓存读取,否则从数据库读取并更新缓存。

  1.  
  1. 适用场景:对数据实时性要求不高,更新比较不频繁,比如签到排行榜
  1.  
  1. 模式2
  1. 如下图,先写入redis然后,利用守护进程等方式,定时写入到数据库
  1. 模式3
  1. 如下图,先写入数据库,然后再更新到缓存
  1.  

  1.  
  1. 适用场景:数据量较大,更新较为频繁
  1.  
  1.  
  1. 说明:
  1. 模式2和模式3的区别在于,前者把redis当作数据库用,通过写入redis后马上返回程序,然后定时把数据写入数据库,这也大大提高了访问速度。这种方式不足的是,这种对redis的可靠性依赖性太强
  1.  
  1. 4案例
  1. ./dbconfig.conf配置
  1. [TESTDB]
  1. host = 192.168.1.103
  1. port = 3306
  1. user = testacc
  1. passwd = test1234
  1. db = testdb
  1. charset = utf8
  1.  
  1. #!/usr/bin/env python
  1. # -*- coding:utf-8 -*-
  1.  
  1. __author__ = 'shouke'
  1.  
  1. import configparser
  1. import sys
  1. import mysql.connector
  1. import redis
  1.  
  1. if __name__ == '__main__':
  1.     pool = redis.ConnectionPool(host='192.168.1.103', port=6379, db=0)
  1.     r = redis.Redis(connection_pool=pool)
  1.     # r.expire('tb_signin_rank:id:signin_num', 20)
  1.  
  1.     config = configparser.ConfigParser()
  1.  
  1.     # 从配置文件中读取数据库服务器IP、域名,端口
  1.     config.read('./dbconfig.conf')
  1.     host = config['TESTDB']['host']
  1.     port = config['TESTDB']['port']
  1.     user = config['TESTDB']['user']
  1.     passwd = config['TESTDB']['passwd']
  1.     db_name = config['TESTDB']['db']
  1.     charset = config['TESTDB']['charset']
  1.  
  1.     try:
  1.         dbconn = mysql.connector.connect(host=host, port=port, user=user, password=passwd, database=db_name, charset=charset)
  1.     except Exception as e:
  1.         print('初始化数据连接失败:%s' % e)
  1.         sys.exit()
  1.  
  1.     # 执行签到
  1.     try:
  1.         db_cursor = dbconn.cursor()
  1.         for id in range(1, 6):
  1.             db_cursor.execute('UPDATE tb_signin_rank SET signin_num = signin_num + 1, signin_time = NOW(), gold_coin = gold_coin + (1 + RAND()*9) WHERE id = %s',(id,))
  1.             db_cursor.execute('commit')
  1.         # 更新缓存
  1.         r.zincrby("tb_signin_rank:id:signin_num", id, 1)
  1.     except Exception as e:
  1.         print('执行数据库更新操作失败:%s' % e)
  1.         db_cursor.execute('rollback')
  1.         db_cursor.close()
  1.         exit()
  1.  
  1.     # 展示用户签到次数
  1.     for id in range(1, 6):
  1.         result = r.zscore('tb_signin_rank:id:signin_num', id)
  1.         if not result: # 不存在缓存,从数据库读取
  1.             print('----从数据库读取用户签到次数----')
  1.             try:
  1.                 db_cursor = dbconn.cursor()
  1.                 db_cursor.execute('SELECT signin_num FROM tb_signin_rank WHERE id = %s', (id,))
  1.                 result = db_cursor.fetchone()[0]
  1.                 # 更新到缓存
  1.                 r.zadd('tb_signin_rank:id:signin_num', id, result)
  1.             except Exception as e:
  1.                 print('执行数据库查询操作失败:%s' % e)
  1.                 db_cursor.close()
  1.         else: # 存在缓存,从缓存读取
  1.             print('----从缓存读取用户签到次数----')
  1.             result = int(result)
  1.  
  1.         print('sigin_num of user[id=%s]: %s' % (id, result))
  1.  
  1.  
  1.     # 展示签到排行榜
  1.     result = r.zrevrange('tb_signin_rank:id:signin_num', 0, 10)
  1.     print('签到排行榜:', result)

  1.  
  1.  
  1. 参考连接:
  1. http://www.cnblogs.com/qq78292959/archive/2013/02/05/2892735.html

Python 基于python+mysql浅谈redis缓存设计与数据库关联数据处理的更多相关文章

  1. $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    $.ajax()方法详解   jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...

  2. 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    很多小伙伴没接触过Redis,以至于去学习的时候感觉云里雾里的,就有一种:教程随你出,懂了算我输的感觉. 每次听圈内人在谈论的时候总是插不上话,小编就偷偷去了解了一下,也算是初入门径. 然后就整理了一 ...

  3. 浅谈HTTP缓存以及后端,前端如何具体实现HTTP缓存

    <浅谈HTPP缓存>原版: https://juejin.im/post/5bdeabbbe51d4505466cd741?utm_source=gold_browser_extensio ...

  4. Python 基于Python实现的ssh兼sftp客户端(上)

    基于Python实现的ssh兼sftp客户端   by:授客 QQ:1033553122 实现功能 实现ssh客户端兼ftp客户端:实现远程连接,执行linux命令,上传下载文件 测试环境 Win7 ...

  5. 浅谈PHP代码设计结构

    浅谈PHP代码设计结构 您的评价:       还行  收藏该经验       coding多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露. 如何看 ...

  6. Redis缓存设计及常见问题

    Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使 用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的 ...

  7. 11.Redis缓存设计

    11.Redis缓存设计11.1 缓存的收益和成本11.2 缓存更新策略11.3 缓存粒度控制11.4 穿透优化11.5 无底洞优化11.6 雪崩优化11.7 热点key重建优化11.8 本章重点回顾

  8. Python 基于Python从mysql表读取千万数据实践

    基于Python 从mysql表读取千万数据实践   by:授客 QQ:1033553122 场景:   有以下两个表,两者都有一个表字段,名为waybill_no,我们需要从tl_waybill_b ...

  9. Python 基于python操纵redis入门介绍

    基于python操纵redis入门介绍 by:授客  QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3.3.2 基于Python操作R ...

随机推荐

  1. Java 实现 Http 请求工具类

    package com.demo.util; import java.io.BufferedReader; import java.io.IOException; import java.io.Inp ...

  2. 纯CSS下拉菜单(希望对有需要的小伙伴有所帮助)

    效果截图(颜色有点丑,请无视): <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  3. 搭建docker环境准备

    Docker平台的基本构成

  4. 视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频

      视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频  2018-07-11 |  标签»下载, 下载工具, 视频 又是视频下载,老生常谈的话题.阿刚同学已在乐软博客多次与大家分享推荐 ...

  5. Tools - UML

    ProcessOn - 在线绘图工具 ProcessOn 支持流程图.思维导图.原型图.UML.网络拓扑图等: 主流的UML图列都支持,可以作为方便快捷的UML工具: PlantUML - 多系统多编 ...

  6. Cellular Traffic Offloading

    Reference: [1] Mobile Data Offload for 3G Networks [2] Mobile Data Offloading through Opportunistic ...

  7. 为什么(2.55).toFixed(1)等于2.5?

    上次遇到了一个奇怪的问题:JS的(2.55).toFixed(1)输出是2.5,而不是四舍五入的2.6,这是为什么呢? 进一步观察: 发现,并不是所有的都不正常,1.55的四舍五入还是对的,为什么2. ...

  8. 远程连接服务器或云数据库上的mysql服务 - 赖大大

    主要问题有两种: 1.mysql的权限问题. 2.服务器的防火墙和数据库的安全组没设好的问题. 1.权限问题: 首先登录上mysql mysql> use mysql;      #使用mysq ...

  9. 使用配置文件自定义Ribbon配置

    1.application.yml——Ribbon配置文件 debug: false spring: application: name: mcc-ribbon-properties cloud: c ...

  10. leetcode — zigzag-conversion

    /** * Source : https://oj.leetcode.com/problems/zigzag-conversion/ * * Created by lverpeng on 2017/6 ...