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

by:授客  QQ:1033553122

测试环境

redis-3.0.7

CentOS 6.5-x86_64

python 3.3.2

基于Python操作Redis

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


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


适用场景:数据量较大,更新较为频繁

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

 
参考连接:
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. JavaScript实现多张图片上传功能

    今天闲着没事,把之前的多张图片上传代码整理了下. 页面主要代码: <div class="upBox upBox2"> <div class="d1&q ...

  2. javascript 内存模型

    我对于 JavaScript 的内存模型一直都比较困惑,很想了解在操作变量的时候,JS 是如何工作的.如果你和我有同样的困惑,希望这篇文章能给你一些启发. 译文,喜欢原文的可以直接拉到底部 当我们声明 ...

  3. 通过shell快速配置J2EE运行环境

    虽然可以通过已经配置好的docker镜像来快速运行相关环境, 但是 现实往往就是这么残酷+有钱很任性的时候 就是给出了一个装好系统的电脑让配置环境,每次的配置环境变量真的很烦 纯体力活 就简单的写个脚 ...

  4. Django--Auth 模块

    1 Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码 ...

  5. 002. Asp.Net Routing与MVC 之(基础知识):HttpModule 与 HttpHandler

    本文By 杨工. 一. Http.sys http.sys 从Win2003和WinXP SP2开始,就成为windows操作系统内核驱动程序,能够让任何应用程序通过它提供的接口,以http协议进行信 ...

  6. Docker应用场景

    Docker的应用场景 Web 应用的自动化打包和发布. 自动化测试和持续集成.发布. 在服务型环境中部署和调整数据库或其他的后台应用. 从头编译或者扩展现有的OpenShift或Cloud Foun ...

  7. PHP-CPP开发扩展(一)

    PHP-CPP是一个用于开发PHP扩展的C++库.PHP-CPP提供了一系列完善的文档.易于使用和扩展的类,让你可以相对快速的创建PHP的原生扩展. 为什么使用PHP-CPP 很快 用C++编写的代码 ...

  8. Spring Boot + Spring Cloud 构建微服务系统(八):分布式链路追踪(Sleuth、Zipkin)

    技术背景 在微服务架构中,随着业务发展,系统拆分导致系统调用链路愈发复杂,一个看似简单的前端请求可能最终需要调用很多次后端服务才能完成,那么当整个请求出现问题时,我们很难得知到底是哪个服务出了问题导致 ...

  9. Spring Boot + Spring Cloud 构建微服务系统(六):熔断监控集群(Turbine)

    Spring Cloud Turbine 上一章我们集成了Hystrix Dashboard,使用Hystrix Dashboard可以看到单个应用内的服务信息,显然这是不够的,我们还需要一个工具能让 ...

  10. 深入理解L1、L2正则化

    过节福利,我们来深入理解下L1与L2正则化. 1 正则化的概念 正则化(Regularization) 是机器学习中对原始损失函数引入额外信息,以便防止过拟合和提高模型泛化性能的一类方法的统称.也就是 ...