Redis
- Redis(REmote DIctionary Server)是一个非常流行的基于内存的轻量级键值数据库(key-value database)。与其把Redis称为一种数据库,不如说Redis是一种数据结构服务器更为恰当。Redis原生地在内存中实现了多种类型的数据结构,并提供了操作这些数据结构的多种API。更加重要的是,作为一个需要长期运行的数据存储服务,Redis还提供了高性能命令处理、高可靠性/扩展性的架构及数据持久化等特性。
Redis时一个完全用C语言编写的开源软件。
Redis中的术语实例代表一个redis-server进程。同一台主机上可以运行多个Redis实例,只要这些实例使用不同的配置即可,比如绑定到不同的端口上、使用不同的路径保存数据持久化相关的文件,或采用不同的日志路径等。
Redis作为一种数据存储服务,如何正确的停止Redis服务端就非常重要了,强烈建议使用shutdown命令。发出shutdown命令后,首先redis-server会停止响应客户端的连接,然后如果启用了持久化,则会执行数据持久化操作,之后,如果.pid文件和socket套接字文件描述符存在的化,则对其进行清理,并最终退出操作。应该注意的是,使用kill命令或其他进程管理工具向Redis进程发送SIGERM(15)信号基本上等同于使用shutdown命令优雅的停止redis-serve。
Redis以其高性能而闻名,它最大程度的利用单线程、非阻塞、多路复用的I/O模型来快速的处理请求。当然在某些情况下,Redis也会创建线程或子进程来执行某些任务。Redis包含了一个简单的但功能强大的异步事件库,称为ac。
Redis基本上就是一个接受并处理来自客户端请求的非阻塞、I/O复用的TCP服务器。虽然Redis服务器很复杂,但我们可以使用各种编程语言通过TCP协议与Redis进行通信。对于Redis来说,这种通信协议叫做REdis Serialization Protocol(RESP,Redis序列化协议)。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用;
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储;
- Redis支持数据的备份,即master-slave模式的数据备份。
-
Redis 优势:
性能极高:Redis能读的速度是110000次/s,写的速度是81000次/s ;
丰富的数据类型:Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作;
原子:Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来;
丰富的特性:Redis还支持 publish/subscribe, 通知, key 过期等等特性。 -
单线程的redis为什么这么快:
纯内存操作;
单线程操作,避免了频繁的上下文切换;
采用了非阻塞I/O多路复用机制。
安装Redis
-
安装编译工具:
sudo apt-get install build-essential -
为Redis创建目录并切换到所创建的目录中:
mkdir /redis
cd /redis -
下载Redis
wget http://download.redis.io/releases/redis-4.0.1.tar.gz -
解压下载的Redis源码并切换到对应的目录下:
tar -zxvf redis-4.0.1.tar.gz
cd redis-4.0.1 -
为Redis的配置文件创建目录并把默认的文件复制进去:
mkdir /redis/conf
cp redis.conf /redis/conf -
编译依赖项:
cd deps
make hiredis lua jemalloc linenoise
cd … -
编译Redis:
make -
安装Redis:
make PREFIX=/redis install -
进入/redis目录并验证生成了Redis的二进制可执行文件:
cd /redis/bin
- Redis遵循如下的标准版本号实践,即major:minor:patch(主版本号:次版本号:补丁版本号)的层次形式。偶数的主版本号代表稳定版,奇数的主版本号表示不稳定。
Memcache与Redis的区别
- 存储方式:Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,Redis可以持久化数据;
- 数据支持类型:memcached所有的值均是简单的字符串,Redis作为其替代者,支持更为丰富的数据类型 ,提供list,set,zset,hash等数据结构的存储;
- 底层模型不同:它们之间底层实现方式以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- value 值大小不同:Redis 最大可以达到 1gb;memcache 只有 1mb。
- Redis的速度比memcached快很多;
- Redis支持数据的备份,即master-slave模式的数据备份。
Redis 为什么是单线程的
-
官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了,Redis利用队列技术将并发访问变为串行访问。
1)绝大部分请求是纯粹的内存操作(非常快速);
2)采用单线程,避免了不必要的上下文切换和竞争条件;
3)非阻塞IO优点:
速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
支持丰富数据类型,支持string,list,set,sorted set,hash
支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除 -
如何解决redis的并发竞争key问题
同时有多个子系统去set一个key。这个时候要注意什么呢? 不推荐使用redis的事务机制。因为我们的生产环境,基本都是Redis集群环境,做了数据分片操作。你一个事务中有涉及到多个key操作的时候,这多个key不一定都存储在同一个redis-server上。因此,redis的事务机制,十分鸡肋。
(1)如果对这个key操作,不要求顺序: 准备一个分布式锁,大家去抢锁,抢到锁就做set操作即可;
(2)如果对这个key操作,要求顺序: 分布式锁+时间戳。 假设这会系统B先抢到锁,将key1设置为{valueB 3:05}。接下来系统A抢到锁,发现自己的valueA的时间戳早于缓存中的时间戳,那就不做set操作了。以此类推。
(3)利用队列,将set方法变成串行访问也可以。redis遇到高并发,如果保证读写key的一致性对Redis的操作都是具有原子性的,是线程安全的操作,你不用考虑并发问题,redis内部已经帮你处理好并发的问题了。
Redis的基本操作
# 1. 启动Redis
$ bin/redis-server
# 启动时指定配置文件的位置
$ bin/redis-server conf