为了提高站点性能,部署了一台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); }
新的业务流程:
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); }
读取数据库数据填充到缓存的问题,及修复方案一则,布布扣,bubuko.com
原文:http://blog.csdn.net/youbl/article/details/37503201