目录:
一, 介绍
二, 缓存问题
三, Redis 内存滥用
四, 键命名规范
五, Redis 使用场景
六, 持久化操作
七,.Net Core 使用 Redis 简单介绍
一, 介绍
1, 高性能 -- Redis 能读的速度是 110000 次 / s, 写的速度是 81000 次 / s ,c 语言实现距离系统更近, 数据存储在内存中, 采用了 epoll, 非阻塞 I/O,
2, 原子性 -- Redis 的所有操作都是原子性的
3, 特性 - 可设置过期键, 支持 publish/subscribe 发布与订阅, 通知等
4, 数据类型 - 支持 String(字符串),Hash(哈希),List(列表),Set(集合), ZSet(有序集合),Bitmaps(位图),HyperLogLog,Geo(地理信息定位)
5, 服务器简单 - 底层代码简单优雅, 不依靠操作系统类库, 单线程模型, 避免并发问题
6, 支持持久化 - RDB,AOF
二, 缓存问题
缓存的更新客区分为三种方式 - 主动更新, 被动更新, 预加载更新
主动更新 - 开发人员操作更新或者通过定时任务自动更新
被动更新 - 当用户操作触发时进行数据缓存更新
预加载更新 - 通过后台去点击查找最新的数据进行覆盖和删除
三, Redis 内存滥用
原因:
1, 数据一直累加, 没有自动清除也没有手动清除, 数据冗余
2, 储存没用的数据过多, 有些可能只用到一个字段却储存了一个对象
3, 冷数据, 根本不会用到的数据没有去管理和清理
解决:
1, 每次存储数据加上过期时间
2, 定期查看是否存在冷数据进行清除
3, 存储对应数据, 不应肆意存储数据. 存储可用到的数据
4, 存储的数据尽量从简, 简化存储的数据
四, 键命名规范
1, Redis 是非关系型数据库, 内存存储数据, 键名长度也会影响空间, 尽量控制键名长度
2, 可考虑大小写命名规范, 根据业务命名, 可加前缀, 通俗易懂
五, Redis 使用场景
1, 最主要用途可做缓存
2, 用 Redis 的有序集合数据结构可做排行榜 (ZSet)
3, 频繁读取数据库会造成数据库的巨大的压力都可以采用 Redis(浏览量, 在线人数, 等等)
4, publish/subscribe 发布与订阅可做简单的消息队列
六, 持久化操作
持久化操作分为两种: RDB 与 AOF 持久化
RDB:
1, 效率更高
2, 性能最大化, 因为开始持久化的时候是 fork 出一个子进程, 然后子进程去完成持久化的工作
3, 会将数据都存储在一个文件当中
持久化的配置
- # 持久化时间策略
- save 900 1 #在 900s 至少有一条写入就会触发一次快照也就是一次备份
- save 300 10 #300s 内至少有 10 条写入就会产生快照
- save 60 10000 #60s 内产生 10000 条写入就会产生快照
- # 如果持久化出错是否停止主进程的写入
- stop-writes-on-bgsave-error yes
- # 是否压缩
- rdbcompression yes
- # 导入时是否检查文件
- rdbchecksum yes
- # 保存的文件的名称
- dbfilename dump.rdb
- # 保存文件地址
- dir ./
stop-writes-on-bgsave-error yes -- 是一条很重要的命令, 为了保证数据的完整性的
rdbcompression yes 没必要开启, 开启会导致 CPU 的消耗. 划不来, 默认开启的
在时间策略上面还有一个 #save "", 这行命令被注释了, 如果想要禁用 RDB 持久化就可以开启这条命令.
RDB 持久化是默认开启的, 而 AOF 是默认关闭的
AOF:
1, 三种持久化的策略: 1, 修改同步 2, 每秒同步 3, 不同步.
2, 写入操作采用的是 append 模式, 即使在操作数据到一半系统崩溃的情况下也可在启动之前用 Redis-check-aof 工具来完成数据的回复的一致性的问题.
- # 是否开启 aof
- appendonly no
- # 文件的名称
- appendfilename "appendonly.aof"
- # 同步方式
- # appendfsync always #修改了就同步, 比较消耗性能, 慢但安全
- appendfsync everysec #每秒同步一次, 比较折中, 默认开启, 最多会损失 1s 的数据
- # appendfsync no #不开启同步, 交给 os 处理, 快但不安全
- #aof 重写期间是否同步
- no-appendfsync-on-rewrite no
- # 重写触发的配置
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb
- # 加载 aof 时有错是否继续加载, 遇见错误会写入一个 log 然后继续执行, 如果是 no 的话会终止执行
- aof-load-truncated yes
定时任务:
- # The range is between 1 and 500, however a value over 100 is usually not
- # a good idea. Most users should use the default of 10 and raise this up to
- # 100 only in environments where very low latency is required.
- hz 10
表示 1s 内执行 10 次, 可设置 1-500 之间的数字, 通常超过 100 不是好的想法, 100 的设置只适合非常低延迟的环境.
七,.Net Core 使用 Redis 简单介绍
1, 引用包 StackExchange.Redis
2, 建立一个 Redis 管理链接类
- public class RedisManager
- {
- static RedisManager()
- {
- if (!string.IsNullOrEmpty(Redis 连接字符串))
- redisHelp = new RedisHelp(Redis 连接字符串);
- }
- public static RedisHelp redisHelp { get; set; }
- }
3, 建立一个 Redis 帮助类
- public class RedisHelp
- {
- private ConnectionMultiplexer Redis { get; set; }
- private IDatabase db { get; set; }
- public RedisHelp(string connection)
- {
- Redis = ConnectionMultiplexer.Connect(connection);
- }
- /// <summary>
- /// 增加 / 修改 string 字符串类型
- /// </summary>
- /// <param name="key"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- public bool SetValue(string key, string value,int timeSpan=0,int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- //var a = TimeSpan.Parse(timeSpan.ToString());
- var result= db.StringSet(key, value);
- if (timeSpan>0)
- {
- db.KeyExpire(key, DateTime.Now.AddSeconds(timeSpan));
- }
- return result;
- }
- /// <summary>
- /// 查询 字符串类型
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public string GetValue(string key, int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- return db.StringGet(key);
- }
- /// <summary>
- /// 删除
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public bool DeleteKey(string key, int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- return db.KeyDelete(key);
- }
- /// <summary>
- /// 键是否存在
- /// </summary>
- /// <param name="key"></param>
- /// <param name="indexDb"></param>
- /// <returns></returns>
- public bool KeyExist(string key,int indexDb=0)
- {
- var db = Redis.GetDatabase(indexDb);
- var result = db.KeyExists(key);
- return result;
- }
- /// <summary>
- /// 哈希写入字符串
- /// </summary>
- /// <param name="key"></param>
- /// <param name="field"></param>
- /// <param name="value"></param>
- /// <param name="timeSpan"></param>
- /// <param name="indexDb"></param>
- public void HashSetString(string key, string field, string value, int timeSpan = 0, int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- db.HashSet(key, field, value);
- if (timeSpan>0)
- {
- db.KeyExpire(key,DateTime.Now.AddSeconds(timeSpan));
- }
- }
- /// <summary>
- /// 获取哈希值 (单个字符串类型)
- /// </summary>
- /// <param name="key"></param>
- /// <param name="field"></param>
- /// <param name="indexDb"></param>
- /// <returns></returns>
- public string HashGetString(string key, string field, int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- if (!string.IsNullOrWhiteSpace(key)&&!string.IsNullOrWhiteSpace(field))
- {
- RedisValue result = db.HashGet(key, field);
- if (!string.IsNullOrWhiteSpace(result))
- {
- return result;
- }
- }
- return string.Empty;
- }
- /// <summary>
- /// 删除哈希
- /// </summary>
- /// <param name="key"></param>
- /// <param name="field"></param>
- /// <param name="indexDb"></param>
- /// <returns></returns>
- public bool DeleteHash(string key, string field, int indexDb = 0)
- {
- var db = Redis.GetDatabase(indexDb);
- return db.HashDelete(key,field);
- }
- }
来源: https://www.cnblogs.com/hulizhong/p/10751529.html