10分钟了解redis原理(java版)

    一直在玩redis,但是不是很了解原理,一个偶然的机会,接触到了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更深层次的理解,可以仔细研究源码.
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值