分布式缓存Redis

What is Redis?

Redis是一个开源的,基于内存的数据结构存储服务器,被用作数据库、缓存、消息代理。它支持的数据结构类型有strings, hashes, lists, sets, sorted setsbitmaps, hyperloglogs, geospatial, StreamRedis有内置的复制,lua脚本,LRU(Least Recently Used最近最少使用)淘汰,事务,磁盘持久化,并提供高可用的Redis Sentinel哨兵和自动分区的Redis Cluster集群。

Redis环境搭建

官网:https://redis.io/

下载:http://download.redis.io/releases/redis-5.0.5.tar.gz 

解压:tar -zxvf redis-5.0.5.tar.gz -C /usr/local

编译:切换到解压后的目录: cd redis-5.0.5,执行命令:make make命令是编译,Linux需要有gcc编译器,如果没有,安装请执行 yum install gcc -y 

测试编译状态:make test  (可以跳过

执行make 后,redis安装完成;

安装说明:

1. 测试编译状态需要安装tcl: yum install tcl -y

2. error: jemalloc/jemalloc.h: No such file or directory提示该错误是Redis在安装时需要有一个内存分配器allocator,如果指定了MALLOC这个环境变量,那么会用这个环境变量的去建立Redis。如果没有,那么就是用默认的分配器,Redis 2.4版本之后,默认使用jemalloc来做内存管,因为jemalloc被证明解决fragmentation problems(内存碎片化问题)libc更好。但是如果你的环境中没有jemalloc而只有libc,所以make会出错,你可以加这么一个参数即可。

解决办法:

make MALLOC=libc

Redis基本配置

redis-server

redis服务器

redis-cli

Redis命令行客户端

redis-benchmark

Redis性能测试工具

redis-check-aof

Aof文件修复工具

redis-sentinel

Sentinel服务器

redis-check-rdb

rdb文件修复工具

mkreleasehdr.sh

编译redis源码时需要用到的一个脚本

redis-trib.rb

官方提供的Redis Cluster的管理工具,因该工具是用ruby开发的,所以需要安装ruby环境。

配置文件

作用

redis.conf

Redis核心配置文件
sentinel.conf

Redis sentinel 哨兵配置文件

在使用Redis之前,建议将安装目录下redis-5.0.5/redis.conf配置文件修改三个配置项:

1、protected-mode no (改为不保护,否则远程访问不了)

2、bind 127.0.0.1 (注释掉,否则只能本机ip访问)

3、daemonize yes (改为yes表示后台启动redis)

启动:切换到 redis-5.0.5/src/ 目录执行命令 ./redis-server ../redis.conf

关闭: 切换到 redis-5.0.5/src/ 目录执行:./redis-cli shutdown 或者 kill pid 或者 kill -9 pid

说明:

Redis默认6379端口是手机键盘上的MERZ,MERZ是一名意大利歌女的名字;

考虑到redis有可能正在将内存的数据同步到硬盘中,强行终止redis进程可能会导致数据丢失,正确停止redis的方式应该是向Redis发送SHUTDOW命令,

redis收到SHUTDOWN命令后,会先断开所有客户端连接,然后根据配置执行持久化,最终完成优雅退出

Redis的windows版本:https://github.com/microsoftarchive/redis/releases

Redis客户端

  直接连接redis (默认ip127.0.0.1,端口6379):./redis-cli 

  指定IP和端口连接redis:./redis-cli -h 127.0.0.1 -p 6379

  测试redis运行是否正常:ping

  redis默认为16个库redis默认自动使用0号库

  切换库命令:select db

  查看当前数据库中key的数目:dbsize

  删除所有库的数据:flushall

  删除当前库的数据:flushdb

  查看redis服务器的统计信息:info

  获得redis的所有配置项:config get *

Redis图形界面客户端

Redis Desktop Manager

官网:https://redisdesktop.com/ 

注意:

远程连接redis需要修改redis安装目录下的redis.conf配置文件:1、bind ip 绑定ip注释掉;2、protected-mode yes 保护模式改为no;

国人开源AnotherRedisDesktopManager

github:https://github.com/qishibo/AnotherRedisDesktopManager

 Redis编程客户端

Jedis

  Jedis源码:https://github.com/xetorthio/jedis

  api文档:http://xetorthio.github.io/jedis/ 

  Jedis是一个很小功能很健全的redis的java客户端其实就是一个jar包,放到项目中,利用该jar包连接和操作redis;

Lettuce 

  Githubhttps://github.com/lettuce-io/lettuce-core 

  官网:https://lettuce.io 

  Lettuce是一个可伸缩线程安全的Redis客户端多个线程可以共享同一个RedisConnection它利用优秀netty NIO框架来高效地管理多个连接。

Redisson

  Github: https://github.com/redisson/redisson 

  官网:https://redisson.org

  2014年1月发布的开源项目,底层也是采用netty进行通信,不支持string数据结构,促使使用者对Redis的关注分离,提供很多分布式相关操作服务,例如,分布式锁,分布式集合;

  Redis支持50多种语言的编程客户端.

Redis数据类型

String类型

  字符串类型是redis中最基本的数据类型,也是使用最多的一种数据类型,它能存储任何形式的字符串,包括二进制数据,byte字节等,也就是说string类型能存储任

何数据,你可以用它存储序列化后的用户对象,json化的对象,甚至图片,视频等,一个key下的string类型允许存储的最大数据容量是512M;

  String类型可以用来存储任何类型的数据; SET,  GET

  String类型可以用来做计数器;  INCR, DECR, INCRBY,DECRBY

list类型

  列表类型可以存储一个字符串列表,按照数据加入的顺序排序,它非常方便地在往列表左右两端添加元素(左边称为头部,右边称为尾部)。 LPUSH,RPUSH

一个list列表最大能存放232次方-1个元素(4294967295, 40多亿个元素)

列表类型内部使用双向链表实现,所以向列表两端添加元素的时间复杂度为O(1), 获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取

头部或尾部的10条记录也是很快的,但是如果尝试访问一个非常大的列表的中间元素,则速度会很慢,因为这是一个时间复杂度O(n)操作。

  使用场景:类似时间轴的应用,每个时间点发生的重大事件存入list形成时间轴;

LPUSH,LRANGE 记住最近的操作,往list列表头部放入元素,取头部的几个元素即为最近记录;

LPUSH,RPOP  可以作为一个消息传递的顺序队列,从左边放入元素,从右边取出元素;LPUSHRPOP

set类型

  set类型是一个无顺序的字符串集合,集合中每个元素都是不同的,也就是不允许有重复数据,多次添加同一个元素,集合中只会有一个该元素一个set集合最大能存

放232次方-1个元素(4294967295, 40多亿个元素)

  集合类型和列表类型的最大的区别是无序性/有序性唯一性/可重复 set类型在redis内部是使用的值为空的散列表(hash table),所以添加或删除元素操作的时间复杂度都是O(1)

  使用场景:跟踪不同的事情,比如:每天的ip访问量使用set做抽奖,把名单放入set,set不会重复,随机弹出元素;

zset类型(sorted set)

  zset类型与set相似,也是一个无重复元素的集合,不同的是zset的每个元素会关联一个分数,这个分数用于对集合元素进行排序;zset中的元素是唯一的,但是每个元素的分数是可以重复的;

  使用场景:实时的数据排行榜,每次数据的更新会更新分数;

hash类型

  Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

过期时间设置

  Redis中提供了Expire命令设置一个键的过期时间,到期以后Redis会自动删除它,实际使用中也经常使用。

EXPIRE命令:EXPIRE key seconds --先设置好数据,然后再设置该key的过期时间;SETEX key seconds value  --在设置数据的同时,可以直接设置过期时间;

其中seconds 参数表示键的过期时间,单位为秒。EXPIRE 返回值为1表示设置成功,0表示设置失败或者key不存在;

keys *  --查看redis中当前数据库0号库所有的key

如果想知道一个key还有多久时间过期,可以使用TTL命令:TTL key

当键不存在时,TTL命令会返回-2 如果key没有设置过期时间,通过TTL命令会返回-1, -1表示永不过期;

如果想取消key的过期时间(使该key恢复成永久的),可以使用PERSIST命令,如果该命令执行成功,清除了过期时间,则返回1 ,否则返回0(key不存在或者本身就是永久的)

EXPIRE命令的seconds命令必须是整数,所以最小单位是1秒,如果想要更精确的设置key的过期时间可以使用PEXPIRE命令,当然实际过程中用秒的单位就够了。PEXPIRE命令的单位是毫秒。即PEXPIRE key 1000与EXPIREkey 1相等,对应的PTTL以毫秒单位获取键的剩余有效时间;

过期key自动删除(自动清理)的原理

  Redis 中的key失效是如何实现的,即失效的key是如何删除的?实际上,Redis 删除失效key的方法主要有两种:

  消极方法:key被访问时如果发现它已经失效,那么就删除它;

  积极方法:周期性地从设置了过期时间的key中选择一部分过期的key删除.对于那些从未被查询的key,即便它们已经过期,消极方式也无法清除,因此Redis会周期性

地随机测试一些key,已过期的key将会被删掉。

  Redis每秒会进行10次操作,具体的流程:1. 随机测试 20 个带有过期信息的key;2. 删除其中已经过期的key;3. 如果超过25%的key被删除,则重复执行步骤1;

这是一个简单的概率算法(trivial probabilistic algorithm),基于假设我们随机抽取的key代表了全部的key空间。

Redis命令大全

  redis英文版命令大全:https://redis.io/commands 

  redis中文版命令大全:http://redisdoc.com/

Redis分布式锁

  关于锁,我们并不陌生,比如Java有线程锁,比如:synchroniz/Lock等.锁的目的很简单,在多线程环境下,对共享资源的访问造成的线程安全问题,通过锁的机制实现资源

 访问互斥.

  什么是分布式锁,为什么我们需要分布式锁?其实最根本的原因就是锁(互斥)的范围发生了变化,因为在分布式架构中,所有的服务都是集群部署,这些应用是隔离的,在多进程访问共享资源的同时,我们需要满足互斥性就需要一个所有进程都看得到的范围,而这个范围可以使用Redis本身或者Zookeeperh或者数据库等外部设施.

  Redis里面提供了一些能够实现互斥特性的命令,比如SETNX key不存在的情况下为key设置值key存在的话就不设置值),那么我们可以基于这命令来去实现锁

 

利用Redis实现分布式锁主要用到三个命令

  1、SETNX 设置key及key的值,如果key存在就设置失败,key不存在就设置成功;2、EXPIRE 设置key的过期时间3、DEL 删除key

 

 

 

 

posted @ 2020-08-17 08:48  蚂蚁style  阅读(218)  评论(0编辑  收藏  举报