一直在玩redis,但是不是很了解原理,一个偶然的机会,接触到了redis源码,把自己学习到的记录下来,方便以后查看,同时也分享出来,供大家学习.
windows如何安装redis,点击:( http://blog.csdn.net/dong_19890208/article/details/52221377)
如何使用redis,参考: ( https://github.com/xetorthio/jedis)
目前流行使用maven管理项目,所以我们可以:
链接地址: https://redis.io/topics/protocol.
其中有这么三点(手动翻译,匆怪):
Simple to implement.(实现简单)
Fast to parse.(解析快速)
Human readable.(可读性强)
在get和set方法执行时,会使用到一些字符,解释如下:
For Simple Strings the first byte of the reply is "+"
For Errors the first byte of the reply is "-"
For Integers the first byte of the reply is ":"
For Bulk Strings the first byte of the reply is "$"
For Arrays the first byte of the reply is "*"
然后,结尾地方都会使用到"\r\n".
这些是什么意思呢?
一个set方法,redis会执行如下:
*3
$3
SET
$3
foo
$3
bar
这些代码解释如下:*3表示有3个数组
第一组数组:$3 ($表示字符形,SET长度为3),SET
第二组数组:$ + key的长度,key为foo,长度为3,表示为$3,foo
第三组数组:$ + value的长度,value为bar,长度为3,表示为$3,bar
通过上面的英文对比,也可猜出其它符号代表什么.
ok,说了这么多,大家也对redis底层有一个了解了,那么我们通过伪代码来说明一下:
windows如何安装redis,点击:( http://blog.csdn.net/dong_19890208/article/details/52221377)
如何使用redis,参考: ( https://github.com/xetorthio/jedis)
目前流行使用maven管理项目,所以我们可以:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
如何使用呢? 只需要在java中:
Jedis jedis = new Jedis("localhost");//或者Jedis("localhost",6379);
jedis.set("foo", "bar");
String value = jedis.get("foo");
使用就是这么简单!
但是底层又是怎么实现的呢?
这要从get,set方法说起:通过查看源码,同时参考官网,我们发现有一个协议:RESP协议(REdis Serialization Protocol),同时使用socket进行通信的.链接地址: https://redis.io/topics/protocol.
其中有这么三点(手动翻译,匆怪):
Simple to implement.(实现简单)
Fast to parse.(解析快速)
Human readable.(可读性强)
在get和set方法执行时,会使用到一些字符,解释如下:
For Simple Strings the first byte of the reply is "+"
For Errors the first byte of the reply is "-"
For Integers the first byte of the reply is ":"
For Bulk Strings the first byte of the reply is "$"
For Arrays the first byte of the reply is "*"
然后,结尾地方都会使用到"\r\n".
这些是什么意思呢?
一个set方法,redis会执行如下:
*3
$3
SET
$3
foo
$3
bar
这些代码解释如下:*3表示有3个数组
第一组数组:$3 ($表示字符形,SET长度为3),SET
第二组数组:$ + key的长度,key为foo,长度为3,表示为$3,foo
第三组数组:$ + value的长度,value为bar,长度为3,表示为$3,bar
通过上面的英文对比,也可猜出其它符号代表什么.
ok,说了这么多,大家也对redis底层有一个了解了,那么我们通过伪代码来说明一下:
package com.springboot.demo;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* <pre>
* Redis模拟器
* 内部就是使用socket实现的,这里会模拟一下socket发送命令
* Redis底层是基于RESP (REdis Serialization Protocol)
* Simple to implement.
* Fast to parse.
* Human readable.
* Redis的持久化有两种:aof和快照
* @author xiaopanzi
* @date 2018-03-07
*/
public class RedisTest {
private Socket socket;
public RedisTest () {
try {
socket = new Socket("localhost", 6379); //这里是本地测试,默认端口
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* <pre>
* 模拟一个set方法
* 设置一个key和值
* *3表示有数组3个
* 第一组数组:$3 (字符形,SET长度为3),SET命令
* 第二组数组:$ + key的长度,key
* 第三组数组:$ + value的长度,value
* @param key
* @param value
* @return set成功后返回的数据
* </pre>
*/
public String set(final String key,String value){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("*3").append("\r\n");
stringBuilder.append("$3").append("\r\n");
stringBuilder.append("SET").append("\r\n");
stringBuilder.append("$").append(key.length()).append("\r\n");
stringBuilder.append(key).append("\r\n");
stringBuilder.append("$").append(value.length()).append("\r\n");
stringBuilder.append(value).append("\r\n");
byte[] bs = new byte[1024];
try {
//把命令发送出去
socket.getOutputStream().write(stringBuilder.toString().getBytes());
//接收返回内容读到bs中,实际上,成功会返回 "+OK\r\n"
socket.getInputStream().read(bs);
} catch (IOException e) {
e.printStackTrace();
}
return new String(bs);
}
/**
* <pre>
* 模拟一个get方法
* 查询一个key
* *2表示有数组2个
* 第一组数组:$3 (字符形,GET长度为3),GET命令
* 第二组数组:$ + key的长度,key
* @param key
* @return get成功后返回的数据
* </pre>
*/
public String get(final String key){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("*2").append("\r\n");
stringBuilder.append("$3").append("\r\n");
stringBuilder.append("GET").append("\r\n");
stringBuilder.append("$").append(key.length()).append("\r\n");
stringBuilder.append(key).append("\r\n");
byte[] bs = new byte[1024];
try {
socket.getOutputStream().write(stringBuilder.toString().getBytes());
socket.getInputStream().read(bs);
} catch (IOException e) {
e.printStackTrace();
}
return new String(bs);
}
public static void main(String[] args) {
//构造一个实例,也可写成 new RedisTest("localhost",6397)形式
RedisTest redisTest = new RedisTest();
//使用set方法
System.out.println(redisTest.set("test", "result"));
//使用get方法
System.out.println(redisTest.get("test"));
}
}
以上定义了一个类,里面有set和get两个方法,一个构造方法,就是这么简单,就模拟实现了redis的存储查询,当然,如果对redis更深层次的理解,可以仔细研究源码.