读取数据库数据填充到缓存的问题,及修复方案一则

业务简述:

为了提高站点性能,部署了一台Redis,把资源从SqlServer数据库中同步到Redis,站点由原来的读取数据库,变更为读取Redis,以利用Redis的高并发提升站点性能目的。

环境说明:

1、假设表名为softs, 记录的更新时间字段名为 updateTime;

2、不考虑数据库的DELETE操作,只考虑INSERT和UPDATE操作;

3、流程中所有时间,都以数据库时间为准,以避免不同服务器之间的时间误差,导致数据遗漏。

4、重要的前提条件:数据库执行INSERT和UPDATE操作时,把记录的updateTime字段更新为SqlServer的当前时间GETDATE();

旧的业务流程:

1、数据同步程序第一次启动时:

a、读取数据库当前时间GETDATE(),作为下一次增量更新的起始时间变量:LastUpdateTime;

b、全量填充:读取SqlServer的全部数据,填充到Redis中。

2、全量填充完成后,通过DataReader获取增量数据,填充到Redis中:

3、保存这一批增量数据中,最大的那个updateTime,作为下一次增量数据的最小时间:LastUpdateTime;

4、休眠一分钟,重复执行步骤2

流程代码如下:

DateTime lastUpdateTime = DateTime.MinValue;
while(true)
{
    string sql = "SELECT * FROM softs with(nolock) WHERE updateTime >= @LastUpdateTime ORDER BY updateTime";
    var sqlPara = new SqlParaMeter("@LastUpdateTime", SqlDataType.DateTime){Value = lastUpdateTime};
    using(var reader = SqlHelper.ExecuteReader(sql, connectionString, sqlPara)
    {
        while(reader.Read())
        {
            DateTime dt = Convert.ToDateTime(reader["updateTime"]);
            if(dt > lastUpdateTime)
                lastUpdateTime = dt;
            // 获取数据,new数据实体,并Protobuf序列化后,填充到Redis
        }
    }
    Thread.Sleep(60000);
}

存在的问题:

DataReader始终读取到数据库的实时数据,即 sql执行前,时间为1;sql执行后,数据读取前,把时间更新为2;数据读取后,读取到的时间是2,而不会是1;

假设这种情况:

1、LastUpdateTime为:2014-7-7 13:54:12,SQL读取到10条记录,这10条记录中,updateTime最大值为:2014-7-7 13:54:14

2、程序循环读取并处理这10条记录,当读取到第3条记录,并处理时;

3、数据库更新了第1条记录和第10条记录,并把这2条记录的updateTime更新为:2014-7-7 13:54:16

4、程序继续循环处理完成,此时得到的下一次待处理的LastUpdateTime为:2014-7-7 13:54:16

问题出现了:第3步更新了2条记录,第10条记录成功处理了,第1条记录的修改,没有映射到Redis,导致脏数据的产生

新的业务流程:

1、等同于旧流程;

2、全量填充完成后,读取数据库当前时间,作为下一次增量数据的最小时间:LastUpdateTime;

3、通过DataReader获取增量数据,填充到Redis中;

4、休眠一分钟,重复执行步骤2

注:重点是把执行SQL前的数据库时间,当成下一次的增量起始时间,缺点是会有一定的数据重复填充,现在Redis压力不大,可以接受,如果希望忽略重复填充,可以在代码里做去重处理。

代码如下:

DateTime lastUpdateTime;
while(true)
{
    DateTime nextUpdateTime = Convert.ToDateTime(SqlHelper.ExecuteScalar("SELECT GETDATE()", connectionString));
    string sql = "SELECT * FROM softs with(nolock) WHERE updateTime >= @LastUpdateTime ORDER BY updateTime";
    var sqlPara = new SqlParaMeter("@LastUpdateTime", SqlDataType.DateTime){Value = lastUpdateTime};
    using(var reader = SqlHelper.ExecuteReader(sql, connectionString, sqlPara)
    {
        while(reader.Read())
        {
            // 获取数据,new数据实体,并Protobuf序列化后,填充到Redis
        }
    }
    lastUpdateTime = nextUpdateTime;
    Thread.Sleep(60000);
}

读取数据库数据填充到缓存的问题,及修复方案一则

时间: 2024-10-09 01:17:07

读取数据库数据填充到缓存的问题,及修复方案一则的相关文章

读取数据库数据,并将数据整合成3D饼图在jsp中显示

首先我将生成饼图的方法独立写成一个PieChar.java类,详细代码如下:(数据库需要自己建,如有需要的话) 1 import java.io.IOException; 2 import java.sql.SQLException; 3 import org.jfree.chart.ChartFactory; 4 import org.jfree.chart.JFreeChart; 5 import org.jfree.data.general.DefaultPieDataset; 6 7 p

python读取数据库数据,读取出的中文乱码问题

最近遇到python读取数据库数据,读取出的中文乱码问题, 网络搜索的基本是: "1. Python文件设置编码 utf-8 (文件前面加上 #encoding=utf-8)2. MySQL数据库charset=utf-83. Python连接MySQL是加上参数 charset=utf84. 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8)" 这些,一一尝试后仍未解决.去数据库查看了下,发现这个出现中文乱码的字段类型是varcha

Java读取数据库数据生成柱状图

此案例是用swing显示数据的.需要引入jfreechart相关包,不同版本可能包不相同,本人用的是 此案例在ssi框架下会报错,不用框架就没问题. Java后台逻辑代码: public class BarChart { ChartPanel frame1; public BarChart() { CategoryDataset dataset = getDataSet(); JFreeChart chart = ChartFactory.createBarChart3D("水果",

C#使用SqlDataReader读取数据库数据时CommandBehavior.CloseConnection参数的作用

主要用在ExecuteReader(c)中,如果想要返回对象前不关闭数据库连接,须要用CommandBehavior.CloseConnection: CloseConnection解决了流读取数据模式下,数据库连接不能有效关闭的情况.当某个XXXDataReader对象在生成时使用了CommandBehavior.CloseConnection,那数据库连接将在XXXDataReader对象关闭时自动关闭. 由于流模式读取数据库的特点,在具体应用时很难确定数据库连接何时才能被关闭,因为读取的动

读取数据库数据并在HighCharts上显示

可以看得出,图表里横纵坐标的数据都是静态的几个数据,因此我们只要从数据库读取出我们想要的横纵坐标值,然后动态赋给Chart就行了. X轴: xAxis: {                     categories: ['周一', '周二', '周三', '周四', '周五', '周六', '周日' ], //X轴的坐标值                     title: {text: '周数'},  //X轴坐标标题                 } Y轴: yAxis: {    

通过mybatis读取数据库数据并提供rest接口访问

1 mysql 创建数据库脚本 -- phpMyAdmin SQL Dump -- version 4.2.11 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: 2016-08-02 18:13:50 -- 服务器版本: 5.6.21 -- PHP Version: 5.6.3 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = &q

nodejs实现,每天定时自动读取数据库数据-生成excel表格-发送给老板邮箱(promise版)

async版:http://blog.csdn.net/zzwwjjdj1/article/details/52129192 写这个版本主要是,promise比较好用,而且,现在已经是nodejs的内置对象了,无须再引用第三方库 -- 需要的工具 数据库    mysql 连接数据库模块 mysql  基本封装: http://blog.csdn.net/zzwwjjdj1/article/details/51991348 自动运行模块   node-schedule 基本使用 : http:/

java 读取数据库数据转化输出XML输出在jsp页面

因为老师实验报告要求,搭建服务端解析XML 下面代码实现转化XML格式也是在网上找的转化代码 输出在jsp页面以便于客户端解析是自己写的 一个类就解决了Test package tests; //三只坚果 import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.apache.crimson.tree.XmlDocument; import javax.xml.pars

json+一般处理程序读取数据库数据

一般处理程序的语法结构 string jsoncallback = context.Request["jsoncallback"]; 声明变量 前台传值使用        string josn = "([";  定义变量接受值        context.Response.ContentType = "text/json";        Cx cc = new Cx();  后台查询的类方法        List<Model>