浅谈Redis与中间的一些设计策略

栏目: 数据库 · 发布时间: 5年前

内容简介:Redis是一个开源的高性能键值对数据库,基于内存且可持久化的日志,所以通常也说内存数据库,提供多种键值数据类型能够适应不同的存储需求,所以这两块构成了Redis强大的基础,基于内存的高性能和支持多种数据类型的高可用。Redis默认支持16个数据库,可以通过配置参数databases来修改。Redis不支持自定义数据库名字,也不支持为不同库设置访问密码,都是以编号来命名的0~15,所以数据库之间并不完全隔离。所以注意不同的应用要使用不同的Redis实例存储数据。Redis中的事务(transaction)是

Redis是一个开源的高性能键值对数据库,基于内存且可持久化的日志,所以通常也说内存数据库,提供多种键值数据类型能够适应不同的存储需求,所以这两块构成了 Redis 强大的基础,基于内存的高性能和支持多种数据类型的高可用。

可执行文件

  • redis-server:Redis服务器
  • redis-cli:Redis命令行客户端
  • redis-benchmark:Redis性能测试工具
  • redis-check-aof:AOF文件修复工具
  • redis-check-dump:RDB文件检查工具

启动和停止

  • 直接启动:适用开发环境 redis-server,默认使用6379端口,可以通过--port参数指定端口号
  • 初始化脚本启动:生产环境 Redis源代码目录utils文件中有一个redis_init_script的初始化脚本文件,使用脚本启动需要配置Redis的运行方式和持久化文件、日志文件的存储位置等。
  • 停止:强制终止进程可能会导致数据丢失,通常是像Redis发送SHUTDOWN命令,kill进程的PID效果一样。 redis-cli SHUTDOWN

多数据库

Redis默认支持16个数据库,可以通过配置参数databases来修改。Redis不支持自定义数据库名字,也不支持为不同库设置访问密码,都是以编号来命名的0~15,所以数据库之间并不完全隔离。所以注意不同的应用要使用不同的Redis实例存储数据。

5种数据类型

  • [string] 字符串类型:最基本的数据类型,能存储任何形式的字符串,包括二进制数据,允许最大容量是512MB

  • [string] 常用命令

    [set/get] 赋值与取值
    [incr] 递增数字
    
  • [hash] 散列类型:字典结构以键值对的形式存储数据,可以包含2 32 -1个字段

  • [hash] 常用命令

    [hset/hget] 赋值与取值
    [hexists] 判断字段是否存在
    [hsetnx] 当字段不存在时赋值
    [hincrby] 增加数字
    [hdel] 删除字段
    
  • [list] 列表类型:存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段,一个列表最多容纳2 32 -1个元素

  • [list] 常用命令

    [lpush/rpush] 向列表两端增加元素
    [lpop/rpop] 从列表两端弹出元素
    [llen] 获取列表中元素的个数
    [lrange] 获取列表片段
    [lrem] 删除列表中指定的值
    
  • [set] 集合类型:和列表类型的区别就是无序且去重

  • [set] 常用命令

    [sadd/srem] 增加/删除元素
    [smembers] 获得集合中的所有元素
    [sismember] 判断元素是否在集合中
    [sdiff/sinter/sunion] 集合间运算
    
  • [sorted set] 有序集合类型:和集合类型的区别就在于有序

  • [sorted set] 常用命令

    [zadd] 增加元素
    [zscore] 获得元素的分数,也可做为判断是否存在
    [zrange/zreverange] 获得排名在某个范围的元素列表
    [zrangebyscore] 获得指定分数范围的元素
    [zincrby] 增加某个元素的分数
    

事务

Redis中的事务(transaction)是 一组命令 的集合,Redis保证一个事务中的所有命令要么都执行,要么都不执行。 Redis事务不支持关系数据库事务提供的回滚(rollback)功能。

过程:mulit-----待执行命令----exec

错误处理

  1. 语法错误:事务中只要有一个命令有语法错误,执行exec后就会直接返回错误,语法正确的命令也不会执行。
  2. 运行错误:执行时错误,如散列类型命令操作集合类型的键,这种错误执行前redis是无法发现的,所以出现这类错误,事务中其它命令会继续执行。

WATCH命令监视一个(或多个) key ,监控一直持续到exec命令(事务中的命令是在exec之后才执行的,所以在mulit命令后可以修改watch监控的键值),如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

UNWATCH取消 WATCH命令对所有 key 的监视。如果在执行 WATCH命令之后, exec命令或 discard命令先被执行了的话,那么就不需要再执行 UNWATCH了。 因为 exec命令会执行事务,而discard取消事务的同时也会取消对所有key的监视。

DISCARD取消事务,放弃执行事务块内的所有命令。

EXPIRE生存时间

在Redis中可以使用expire命令设置一个键的生存时间,到时间后Redis会自动删除它。

命令格式:expire key seconds,seconds参数表示键的生存时间,单位为秒。

取消使用persist命令

访问频率限制

通过使用incr命令递增键值来描述次数,通过设置生存时间来自动删除,从而达到限制访问的频率,同时为了保证建立键和为键设置生存时间一起执行(避免某些问题导致中间推出,避免未能设置生存时间而变成永久键),可以把事务也引用进来。

//伪代码
isKeyExists = EXISTS limiting:IP
if isKeyExists is 1
   times = INCR limiting:ip
   if times >100
      print 访问频率超过限制
      exit
   else
      MULTI
      INCR limiting:ip
      EXPIRE keyName ,60
      exit
复制代码

实现缓存

上面说到使用expire命令来设置了生存时间,就可以用来满足缓存实现的要求,但是为了提高缓存的命用率以及更合理的使用内存资源,需要让Redis按照一定的规则淘汰不需要的缓存键

淘汰规则

规则 说明
volatile-lru 使用LRU算法删除一个键(已设置生存时间的键)
allkeys-lru 使用LRU算法删除一个键
volatile-random 随机删除一个键(已设置生存时间的键)
allkeys-random 随机删除一个键
volatile-ttl 删除生存时间最近的一个键
noeviction 不删除,只返回错误

排序

前面说到了列表类型,有序集合类型都是满足有序的,这里讲讲怎么完成排序。 sort命令

sort命令可以对列表类型、集合类型和有序集合类型的键进行排序,还可以通过 ALPHA 参数实现按照字典顺序排列, DESC 参数倒序等。 by参数

如果提供了by参数,sort命令将不再依据元素自身的值进行排序,而是对每个元素使用元素的值替换参考键中的第一个 “*” 并获取其值,然后依据该值对元素排序

## 键名->字段名
sort tag:posts by  post:*->time desc
复制代码

get参数

get参数不影响排序,它的作用是使sort命令的返回结果不再是元素自身的值,而是get参数中指定的键值。

store参数

默认情况下sort会直接返回 排序 结果,如果希望保存结果,需要使用store参数

性能优化

sort是redis种最强大最复杂的命令之一,时间复杂度是O(n+mlogm),n表示排序的元素个数,m表示返回的元素个数。

  1. 尽可能减少待排序键中元素的数量,n尽可能小。
  2. 使用limit参数只获取需要的数据,m尽可能小。
  3. 如果要排序的数据数量较大,尽可能使用store参数将结果缓存。

消息

任务队列说到队列通常使用的是Redis的列表类型,使用lpush和rpop命令实现队列。只需要让生产者将任务使用lpush命令加入到某个键中,另一边让消费者不断使用rpop命令从该键中取出任务即可。 优先级队列

可以通过brpop命令来解决,brpop可以同时接收多个键,意义是同时检测多个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素则会从该键中弹出元素,如果多个键都有元素则按照从左到右的顺序去第一个键中的元素。借此特性可以实现区分优先级的任务队列。

发布/订阅

Redis提供了一组命令可以让开发者实现发布/订阅(publish/subscribe)模式。该模式包含了两种角色,发布者和订阅者;可以用来实现消息通知等。 订阅者可以订阅一个或者若干个频道(channel),而发布者可以向指定的频道发送消息,订阅该频道都会收到此消息。

管道

客户端和Redis使用TCP协议连接,无论是发送命令还是返回执行结果都需要经过网络传输,如果执行的命令较多,延时的累加起来对性能还是有一定影响。 管道(pipelining)可以一次性发送多条命令并在执行完后一次性将结果返回。

优化空间

  1. 精简键名和键值
  2. 内部编码优化

持久化

Redis支持两种方式的持久化,RDB方式、AOF方式,可单独使用,也可两者结合使用。

  1. RDB :通过快照(snapshotting)完成的,当符合一定条件时Redis自动将内存中的所有数据进行快照并存储到硬盘。由用户在配置文件中自定义,两个参数构成: 时间和改动的键个数 ;指定时间内更改的键大于这个数值就会进行快照。 默认采用这种持久化方式
    缺点是定时持久化
  2. AOF :通过appendonly参数开启,开启后每执行一条更改的命令,会将该命令写入硬盘的AOF文件,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍。AOF文件位置和RDB文件的位置相同,都是通过dir参数设置,将缓存内容同步到硬盘中 默认情况下采用everysec规则,即每秒执行一次同步操作,always表示每次写入都执行同步,最安全也最慢,no表示不主动进行同步而交由操作系统(默认30秒一次),都是通过appendfsync参数设置

多机数据库

主要是适用于大型分布式场景

  1. 复制 :简洁来说就是主从复制,主数据库(master),从数据库(slave);主数据库可以进行读写操作,发生写操作时候同步给从数据库,从数据库一般只负责读。
  • 使用复制功能很简单,在配置文件中加入“slaveof 主数据 ip 主数据库端口”即可。
  • 当从数据库启动后,会向主数据库发送sync命令,主数据库接收后开始后台保存快照及期间接收的命令缓存起来,快照完成后,将快照文件和缓存的命令发送给从数据库。从数据库接收会载入快照文件及执行缓存命令。不支持断点续传。
  • 基于复制可以实现读写分离,以及可以通过主从切换来提高数据库的高可用。比如设置主禁用持久化,从开启持久化,主数据库挂掉后,可以把从数据库提升为主数据库,主数据库重启后设置为从数据库即可将数据同步过来。这样能保证数据不会丢失。
  1. sentinel :哨兵,Redis的高可用解决方案之一,由一个或多个sentinel实例组成的sentinel系统可以监视多个主服务器,以及这些主服务器下的所有从服务器,主服务器下线后自动将下属某个从服务器升级为新的主服务器。
  2. 集群 :Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mathematica Cookbook

Mathematica Cookbook

Sal Mangano / O'Reilly Media / 2009 / GBP 51.99

As the leading software application for symbolic mathematics, Mathematica is standard in many environments that rely on math, such as science, engineering, financial analysis, software development, an......一起来看看 《Mathematica Cookbook》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具