Redis 学习笔记总结

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 学习笔记总结相关的知识,希望对你有一定的参考价值。

文章目录

1. Redis 的配置文件(redis.conf) 详解

有篇不错的配置详解可以直接查看这一篇:https://www.cnblogs.com/xiaoxi-jinchen/p/14566146.html

1.1 redis.conf文件的 Units 单位


配置大小单位,在redis配置文件中,只支持bytes字节单位,不支持bit。

配置文件中,大小写不敏感。

1.2 redis.conf文件的 include包含(导入外部配置文件)


1.3 redis.conf文件的 network(网络相关配置)

1.2.1 bind 配置使用


默认情况下,bind=127.0.0.1 只能接受本地的访问请求,也就是别人通通过远程连接没法访问你的redis。

如果不写或注释掉上面的127.0.0.1,则就无限制接受任何ip地址的访问。

1.2.2 protected-mode 和 port 配置


protected-mode 设置为yes,开启redis服务的保护设置。他只能以本机访问远程不可以!

port就是端口号,默认就是6379,一般不用改!

设置完protected-mode和注释bind后,我们重启查看服务就变成了*号:


别人远程连接redis数据库,见下图:

提一点:使用ps -el查看进程格式,使用ps -aux可以更加详细看进程的信息,方便我们查看redis的服务进程。

1.2.3 tcp-backlog 配置


redis.conf配置文件中的network模板下的,tcp-backlog配置,backlog其实是一个连接队列。

backlog队列总和 = 未完成三次握手队列 + 已经完成三次握手队列。

下图了解一下就可以:

1.2.4 tcp-backlog 配置


timeout配置,设置超时时长(以秒为单位)。 如果写成了0,就代表永不超时。

1.2.5 tcp-keepalive 配置



tcp-keepalive配置就是一个心跳时间。这里说不准,可以理解为300秒内有操作,说明还活着,就提供服务;反之,说明没有活着,就断开连接。

1.4 redis.conf文件的 general

1.4.1 daemonize 配置


daemonize配置:设置是否守护进程。

1.4.2 pidfile 配置


pidfile配置存放pid文件的位置,这里的pid文件就是用来保存进程号的文件(简称,pid文件)。每个实例会产生一个不同的pid文件。

我们可以去相关地址,cat一下这个文件:

1.4.3 loglevel 配置


loglevel配置日志级别。

1.4.4 logfile 配置


logfile配置,设置log日志的输出位置。


1.4.5 databases 配置


databases配置,默认就是16个数据库也没必要改。

1.5 redis.conf文件的 security(安全)


这里只说一个密码问题:

redis默认是没有密码的!

在命令中设置密码,只是临时的。重启redis服务器,密码就还原了!

想要永久设置密码,还需要配置文件中进行配置。

命令方式设置密码:

1.6 redis.conf文件的 limit(限制)

1.6.1 maxclients 配置



1.6.2 maxmemory 配置



1.6.3 maxmemory-policy 配置


1.6.4 maxmemory-samples 配置


maxmemory-samples 配置是一个样本操作,从其中抽出几个查看,如果合格,就象征着合格。不精确


2. Redis的 发布和订阅


Redis 发布订阅(pub / sub) 是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接受消息。

Redis客户端可以订阅任意数量的频道。

发布者发送消息,那么订阅者通过频道来接受到消息。


订阅命令:

  • subscribe channel_name 命令:这个命令是当前客户端,订阅了channel_name频道。

发送命令:

  • publish channel_name comment 命令:这个命令向channel_name频道发送一个comment的内容。

3. Redis6新数据类型 Bitmaps

3.1 Bitmaps数据类型 介绍


了解位的概念。

bitmaps的原理就是通过位操作来实现的。

3.2 Bitmaps的 命令


setbit key_name offset value 命令:设置Bitmaps中某个偏移量的值,这个值只能是0或1。


getbit key_name offset 获取bitmaps中某个偏移量的值,当然获取到的值,只能是0或1。


bitcount key_name [start , end] 命令:统计字符串被设置为1的bit数。

注意这个start和end有些不同! 它是根据8个bit来分组的。


bitop [and / or / not / xor] destkey [key …] 命令:bitop是一个复合操作。将[key …]的进行and与, or或,not 非,xor异或的操作,将结果返回给destkey。

这里很简单,就是比较多个key的位,进行与或非异或的操作。


一般bitmaps要比set有优势!因为bitmaps是在位的层次上进行操作。

4. Redis6新数据类型 HyperLogLog

4.1 HyperLogLog数据结构 介绍


平时,我们工作像什么PV(PageView 页面访问量),可以使用Redis的incr, incrby 轻松实现。

但像这种UK(Unique Visitor , 独立访客),独立IP数,搜索等需要去重和计数的问题。这种求集合中不重复元素个数的问题成为基数问题。



Redis退出的HyperLogLog就是用来做基数统计的算法。

4.2 HyperLogLog的 命令


pfadd key_name element [element…] 命令:添加指定元素到HyperLogLog中去。


pfcount key_name命令:得到key_name的基数数量。


pfmerge destkey sourcekey [sourcekey …] 命令:将一个或多个HLL(HyperLogLog)合并后的结果存储在另一个HLL中,比如每月活跃用户可以使用每天的活跃用户来合并计算可得。

5. Redis6新数据类型 Geospatial

5.1 Geospatial数据结构 介绍


Geo类型,就是Geographic 地理信息的缩写

5.2 Geospatial的 命令


geoadd key_name longitude latitude memeber [longitude latitude memeber…] 命令:添加地理位置(经度,纬度,名称)。



geopos key_name member [member…] 命令:获得指定地区的坐标值。


geodist key_name member1 member2 [ m | km | ft | mi ] 命令:获取两个位置之间的直线距离。



默认使用米作为单位。


georadius key_name longitude latitude radius [ m | km | ft | mi ] 命令:以给定的经纬度为中心,找出某一半径内的元素。

6. Jedis操作Redis数据库

6.1 Jedis的 测试


通过java代码来操作redis数据库,就像jdbc操作mysql一样。

第一步:导包导入依赖。

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.3.0</version>
</dependency>

第二步:Java代码测试,是否能连接成功。
如果不成功,则可能是下面几种情况:

  • 配置文件bind只绑定了本地。
  • 配置文件protected-mode为yes。
  • 改了上面的文件,但是redis服务没有重启,service redis restart就可。
  • 防火墙开启了拦截。
  • 特殊情况:我用的是云服务器,需要配置出入规则。
package com.itholmes.jedis;

import redis.clients.jedis.Jedis;

public class JedisDemo1 
	public static void main(String[] args) 
		
		//创建Jedis对象
		//查看源码可以看到能传两个参数一个是ip地址,一个是端口号。
		Jedis jedis = new Jedis("39.103.163.156",6379);
		
		//测试,如果成功则返回PONG的字符串。
		String ping = jedis.ping();
		System.out.println(ping);
		
	


//jedis一定要close一下
jedis.close();

6.2 Jedis 基本操作


package com.itholmes.jedis;

import java.util.Set;
import org.junit.Test;
import redis.clients.jedis.Jedis;

public class JedisDemo1 
	
	@Test
	public void demo1() 
		//创建Jedis对象
		Jedis jedis = new Jedis("39.103.163.156",6379);
		
		//set方法:设置键值对
		jedis.set("key1","value1");
		jedis.set("key2","value2");
		jedis.set("key3","value3");
		
		//查询全部的key值。
		Set<String> keys = jedis.keys("*");
		for(String set : keys) 
			System.out.println(set);
		
		
		//查看set里面有多少数据
		System.out.println(keys.size());
		
		System.out.println("查看key1是否存在:"+jedis.exists("key1"));
		System.out.println("查看key1还有多久过期:"+jedis.ttl("key1"));
		System.out.println("获取key1的值:"+jedis.get("key1"));
	


//jedis一定要close一下
jedis.close();

6.3 Jedis 基本操作(String)


//创建Jedis对象
Jedis jedis = new Jedis("39.103.163.156",6379);

//设置多个key值,mset方法。
jedis.mset("str1","v1","str2","v2","str3","v3");
//获取多个key值,mget方法。
System.out.println(jedis.mget("str1","str2","str3"));

//jedis一定要close一下
jedis.close();

6.4 Jedis 基本操作(List)


//创建Jedis对象
Jedis jedis = new Jedis("39.103.163.156",6379);

//lpush方法:添加一个list类型的数据。
jedis.lpush("keylist", "lucy","mary","jack");

//lrange方法:访问keylist中所有的数据。
List<String> list = jedis.lrange("keylist", 0, -1);

for(String s : list) 
	System.out.println(s);


//jedis一定要close一下
jedis.close();

6.5 Jedis 基本操作(List)


//创建Jedis对象
Jedis jedis = new Jedis("39.103.163.156",6379);

//像set类型的orders中,添加成员元素。
jedis.sadd("orders", "member01");
jedis.sadd("orders", "member02");
jedis.sadd("orders", "member03");
jedis.sadd("orders", "member04");

//遍历set类型的数据。
Set<String> smembers = jedis.smembers("orders");
for(String order : smembers) 
	System.out.println(order);


//从set类型数据中移除某成员。
jedis.srem("orders", "member02");

System.out.println("remove之后:");

Set<String> smembers2 = jedis.smembers("orders");
for(String order : smembers2) 
	System.out.println(order);


//jedis一定要close一下
jedis.close();

6.6 Jedis 基本操作(hash)


//创建Jedis对象
Jedis jedis = new Jedis("39.103.163.156",6379);

//hset方法:设置一个hash类型的数据。
jedis.hset("hash1", "field1","value1");
//hget方法:获取hash1中field1对应的值。
System.out.println(jedis.hget("hash1", "field1"));

Map<String,String> map = new HashMap<String, String>;
map.put("telphone", "1234567");
map.put("email","29390@qq.com");
map.put("address", "beijing");

//hmset方法,可以直接传给它map类型。
//hmset方法和上面的hset方法区别就是前者能传入多个,后者只能传入一个。
jedis.hmset("hash2", map);

//使用hmget方法来获取,同样hmget方法可以获取多个field值。
List<String> result = jedis.hmget("hash2", "telphone","email");
for(String element: result) 
System.out.println(element);


//jedis一定要close一下
jedis.close();

6.7 Jedis 基本操作(hash)


//创建Jedis对象
Jedis jedis = new Jedis("39.103.163.156",6379);

//zadd方法:添加一个zset有序集合类型的数据。
jedis.zadd("china", 100,"shanghai");
jedis.zadd("china", 100,"beijing");
jedis.zadd("china", 100,"shenzhen");

//zrange方法:遍历有序集合的方法
Set<String> china = jedis.zrange("china", 0, -1);
System.out.println(china);

//jedis一定要close一下
jedis.close();

7. 模拟验证码发送


这种实现功能思路很明确,建议这样方式来实现功能。总之就是,什么样的逻辑需求,对应使用什么样的功能代码来实现。

package com.itholmes.jedis;

import java.util.Random;

import redis.clients.jedis.Jedis;

public class PhoneCode 
	//模拟验证码的过程的测试。
	public static void main(String[] args) 

		//模拟发送验证码:
		//verifyCode("13183751111");
		
		//验证码的验证:
		getRedisCode("13183751111","935067");
	
	
	//1.生成6位数字验证码
	public static String getCode() 
		Random random = new Random();
		
		String code = "";
		
		for(int i=0;i<6;i++) 
			//随机生成10以内的一个数字
			int rand = random.nextInt(10);
			code += rand;
		
		
		return code;
	
	
	//2. 每个手机每天只能发送三次,验证码放到redis中,设置过期时间
	public static void verifyCode(String phone) 
		//连接redis
		Jedis jedis = new Jedis("39.103.163.156",6379);
		
		//拼接key
		//手机发送次数
		String countKey = "VerifyCode"+phone+":count";
		//验证码key
		String codeKey = "VerifyCode"+phone+"code";
		
		//每个手机每天只能发送三次
		String count = jedis.get(countKey);
		if(count == null) 
			//表示没有发送次数,也就是第一次发送
			//第一次发送有效时间就是24小时,换算为秒就是下面了。
			jedis.setex(countKey, 24*60*60, "1");
		else if(Integer.parseInt(count) <= 2) 
			//发送次数+1
			jedis.incr(countKey);
		else if(Integer.parseInt(count) > 2)
			//发送三次,不能在发送了
			System.out.println("今天的发送次数已经超过了三次。");
			jedis.close();
			return;
		
		
		//发送的验证码发到redis里面去
		String vcode = getCode();
		//设置过期时长2分钟
		jedis.setex(codeKey, 60*2, vcode);
		
		jedis.close();
	
	
	//3. 验证码校验
	public static void getRedisCode(String phone , String Code) 
		Jedis jedis = new Jedis("39.103.163.156",6379);
		//从redis获取验证码
		
		//验证码的key
		String codeKey = "VerifyCode"+phone+"code";
		String redisCode = jedis.get(codeKey);
		
		//判断验证码是否相同
		if(redisCode.equals(Code)以上是关于Redis 学习笔记总结的主要内容,如果未能解决你的问题,请参考以下文章

数据结构学习笔记——基数排序和排序算法总结

Redis笔记- HyperLogLog

Redis学习笔记13Redis数据类型之HyperLogLogs类型

Redis 学习笔记总结

Redis 学习笔记总结

萌新笔记——Cardinality Estimation算法学习(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)