基础篇
Redis介绍
什么是Redis?
- Redis是C语言开发的一个开源的高性能键值对(Key-Value)内存数据库
- 它提供五种数据类型来存储值:字符串(string)、散列类型(hash)、列表类型(list)、集合类型(set)、有序集合类型(sortedSet、zSet)
- 它是一种NoSQL数据库
什么是NoSQL?
- NoSQL,即Not-Only SQL(不仅仅是SQL),泛指非关系型的数据库
- 什么是关系型数据库?数据结构是一种有行有列的数据库
- NoSQL数据库是为了解决高并发、高可用、高可扩展、大数据存储问题而产生的数据库解决方案
- NoSQL可以作为关系型数据的良好补充,但是不能替代关系型数据库
NoSQL数据库分类
- 相关产品:Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
- 典型应用:内容缓存,主要用于处理大量数据的高访问负载
- 数据模型:一系列键值对
- 优势:快速查询
- 劣势:存储的数据缺少结构化
- 相关产品:Cassandra、HBase、Riak
- 典型应用:分布式的文件系统
- 数据模型:以列簇存储,将同一列数据存在一起
- 优势:查找速度快,可扩展性强,更容易进行分布式扩展
- 劣势:功能相对局限
- 相关产品:CouchDB、MongoDB
- 典型应用:Web应用(与Key-Value类似,Value是结构化的)
- 数据模型:一系列键值对
- 优势:数据结构要求不严格
- 劣势:
- 相关产品:Neo4J、InfoGrid、Infinite Graph
- 典型应用:社交网络
- 数据模型:图结构
- 优势:利用图结构相关算法
- 劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案
Redis发展历史
- 2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo便 对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并于2009年开发完成,这个数据库就是Redis。
- 不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。
- Salvatore Sanfilippo自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。Hacker News在2012年发布了一份数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、街旁网、知乎网,国外如GitHub、Stack Overflow、Flickr等都是Redis的用户。
- VMware公司从2010年开始赞助Redis的开发, Salvatore Sanfilippo和Pieter Noordhuis也分别在3月和5月加入VMware,全职开发Redis。
Redis应用场景
- 内存数据库(登录信息、购物车信息、用户浏览记录等)
- 缓存服务器(商品数据、广告数据等)(最多使用)
- 解决分布式集群架构中的session分离问题(session共享)
- 任务队列(秒杀、抢购、12306等等)
- 分布式锁的实现
- 支持发布订阅的消息模式
- 应用排行榜
- 网站访问统计
- 数据过期处理(可以精确到毫秒)
Redis单机版安装配置
Redis下载
- 官网地址:http://redis.io/
- 中文官网地址:http://www.redis.cn/
- 下载地址:http://download.redis.io/releases/
Redis安装环境
- Redis没有官方的windows版本,所以建议在linux系统上安装运行,我们使用CentOS 7作为安装环境
- 安装镜像:CentOS-7-x86_64-DVD-1810.iso
Redis安装
yum install -y gcc-c++
yum install -y wget
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar -zxf redis-3.2.9.tar.gz
- 编译Redis源码,进入redis-3.2.9目录,执行编译命令
cd redis-3.2.9
make
make install PREFIX=/usr/local/server/redis
* redis-server:启动redis服务
* redis-cli:进入redis命令客户端
* redis-benchmark:性能监测工具
* redis-check-aof:aof文件进行检查的工具
* redis-check-rdb:rdb文件进行检查的工具
* redis-sentinel:启动哨兵监控服务
Redis启动
前端启动
- 启动命令:redis-server,直接运行 bin/redis-server将以前端模式启动
- 关闭命令:Ctrl+C
- 启动缺点:客户端关闭则redis-server程序结束,不推荐使用此方法
- 启动图例:
后端启动(守护进程启动)
- 第一步:拷贝redis-3.2.9/redis.config配置文件到Redis安装目录的bin目录
cp redis.config /usr/local/server/redis/bin
vim redis.conf
daemonize yes
protected-mode no
./redis-server redis.conf
后端启动的关闭方式
./redis-cli shutdown
Redis命令行客户端
./redis-cli -h 127.0.0.1 -p 6379
* -h:redis服务器的IP地址
* -p:redis实例的端口号
- 默认方式:如果不指定主机和端口号,也可以(默认地址是127.0.0.1;默认端口是6379)
./redis-cli
Java客户端Jedis
Jedis 介绍
- Redis不仅使用命令来操作,而且可以使用程序客户端操作。现在基本上主流的语言都有客户端支持,比如java、C、C#、C++、php、Node.js、Go等。
- 在官方网站里列一些Java的客户端,有Jedis、Redisson、Jredis、JDBC-Redis等其中官方推荐使用 Jedis 和 Redisson,在企业中用的最多的就是Jedis。
- Jedis同样也是托管在github上,地址:添加链接描述
Jedis 使用
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
测试Jedis连通性
public class RedisTest {
@Test
public void testJedis() throws Exception{
Jedis jedis = new Jedis("192.168.254.128", 6379);
System.out.println(jedis.ping());
jedis.close();
}
}
- 打印出PONG,证明本地连接Redis正常
使用连接池连接
@Test
public void testJedisPool() {
JedisPool jedisPool = new JedisPool("192.168.254.128", 6379);
Jedis jedis = jedisPool.getResource();
jedis.set("mytest", "hello world, this is jedis client");
String result = jedis.get("mytest");
System.out.println(result);
jedis.close();
jedisPool.close();
}
Jedis连接集群
- 同样也需要开放防火墙端口,或者直接关闭防火墙,CentOS 7 查看防火墙状态命令:systemctl status firewalld.service。
- 执行后可以看到绿色字样标注的**“active(running)”**,说明防火墙是开启状态
- 使用命令:systemctl stop firewalld.service 关闭运行的防火墙
- 关闭后,使用命令 systemctl status firewalld.service 查看防火墙状态,可以看到,**indisavtive(dead)**的字样,说明防火墙已经关闭
- 前面的方法,一旦重启操作系统,防火墙就自动开启了,该怎么设置才能永久关闭防火墙呢?
- 输入命令:systemctl disable firewalld.service,禁止防火墙服务器
- 代码实现:使用 JedisCluster 连接Redis集群:
@Test
public void testJedisCluster() throws Exception{
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.254.128", 7001));
nodes.add(new HostAndPort("192.168.254.128", 7002));
nodes.add(new HostAndPort("192.168.254.128", 7003));
nodes.add(new HostAndPort("192.168.254.128", 7004));
nodes.add(new HostAndPort("192.168.254.128", 7005));
nodes.add(new HostAndPort("192.168.254.128", 7006));
JedisCluster cluster = new JedisCluster(nodes);
cluster.set("cluster-test", "my jedis cluster test");
String result = cluster.get("cluster-test");
System.out.println(result);
cluster.close();
}
- 测试成功:
Jedis整合Spring
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="30"/>
<property name="maxIdle" value="10"/>
<property name="numTestsPerEvictionRun" value="1024"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="softMinEvictableIdleTimeMillis" value="10000"/>
<property name="maxWaitMillis" value="1500"/>
<property name="testOnBorrow" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="blockWhenExhausted" value="false"/>
</bean>
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg index="0">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7001"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7002"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7003"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7004"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7005"/>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.254.128"/>
<constructor-arg index="1" value="7006"/>
</bean>
</set>
</constructor-arg>
<constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
</bean>
</beans>
public class RedisSpringTest {
private ApplicationContext applicationContext;
@Before
public void init(){
applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
@Test
public void testJedisCluster(){
JedisCluster cluster = (JedisCluster)applicationContext.getBean("jedisCluster");
cluster.set("name", "zhangsan");
String value = cluster.get("name");
System.out.println(value);
}
}