zoukankan      html  css  js  c++  java
  • redis基础----->redis的基本使用(一)

      这里我们就在虚拟机中安装redis,并且使用java和python实现简单的操作。深情是我承担不起的重担,情话只是偶尔兑现的谎言。

    redis的使用

    下载地址:https://redis.io/。安装过程,可以参考博客:http://www.linuxidc.com/Linux/2014-05/101544.htm

    启动服务,参考博客:http://www.linuxidc.com/Linux/2014-05/101544p2.htm

    一、非本地访问redis服务器,需要修改redis.conf文件的内容

    redis.conf文件的位置:tar解压的位置/redis.3.2.8里面。

    • 注释bind 127.0.0.1,使所有的主机都可以访问
    • 修改protected-mode的yes为no

    如果要生效还需要先停掉redis的服务,再redis-server redis.conf。这个redis.conf需要带上。

    参考博客: http://blog.csdn.net/only1994/article/details/52785306

    二、java的测试使用

    依赖jar包:jedis-2.9.0.jar和commons-pool2-2.4.2.jar。使用maven,需要在pom.xml文件中添加内容:

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    具体的java代码如下:

    public void redis_1() {
        Jedis jedis = new Jedis("192.168.146.131", 6379); // 测试用的是虚拟机
        jedis.set("foo", "bar");
        String value = jedis.get("foo");
        jedis.close();
        System.out.println(value); // foo
    }

    三、对于Jedis原理的理解

    我们通过socket连接redis服务器,发送请求命令的数据,然后打印返回的数据。

    package com.linux.huhx.redis;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.Socket;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-23 下午 5:48
     */
    public class RedisTest {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("localhost", 6379);
            socket.setReuseAddress(true);
            String data = "get username
    ";
            socket.getOutputStream().write(data.getBytes());
    
            InputStream inputStream = socket.getInputStream();
            int length = inputStream.available();
            byte[] buffer = new byte[length];
            inputStream.read(buffer);
    
            // 对buffer做处理
            String string = new String(buffer, "utf-8");
            System.out.println(string);
            socket.close();
        }
    }

    如下是打印的结果,可以得到redis中username对应的value。

    $4
    huhx

      其实上述JRedis的原理和这个差不多,都是通过socket连接,发送命令数据到服务器。然后得到响应的数据,现在我们就JRedis的源码对这个流程做一个分析。首先是Jedis jedis = new Jedis("127.0.0.1", 6379);初始化Connection的地址和端口。

    public Connection(final String host, final int port) {
        this.host = host;
        this.port = port;
    }

    String value = jedis.get("username");这段代码的源码如下:

    public String get(final String key) {
        checkIsInMultiOrPipeline();
        client.sendCommand(Protocol.Command.GET, key);
        return client.getBulkReply();
    }

    checkIsInMultiOrPipeline方法是检查Multi和Pipeline,具体的这两个是开什么的,目前不怎么了解。后续补上

    protected void checkIsInMultiOrPipeline() {
        if (client.isInMulti()) {
          throw new JedisDataException(
              "Cannot use Jedis when in Multi. Please use Transation or reset jedis state.");
        } else if (pipeline != null && pipeline.hasPipelinedResponse()) {
          throw new JedisDataException(
              "Cannot use Jedis when in Pipeline. Please use Pipeline or reset jedis state .");
        }
    }

    我们的重点代码是client.sendCommand(Protocol.Command.GET, key);如下:

    protected Connection sendCommand(final Command cmd, final String... args) {
        // 对请求的参数utf-8编码
        final byte[][] bargs = new byte[args.length][];
        for (int i = 0; i < args.length; i++) {
          bargs[i] = SafeEncoder.encode(args[i]);
        }
        return sendCommand(cmd, bargs);
    }

    sendCommand的方法如下:

    protected Connection sendCommand(final Command cmd, final byte[]... args) {
        try {
       // 建立socket连接,socket是一个keep active的连接,这个方法在建立连接之前会检查是否是连接状态的。
          connect();
          // 用上述的socket发送数据,对于发送的数据Jredis做了一些处理
          Protocol.sendCommand(outputStream, cmd, args);
          pipelinedCommands++;
          return this;
        } catch (JedisConnectionException ex) {
          /*
           * When client send request which formed by invalid protocol, Redis send back error message
           * before close connection. We try to read it to provide reason of failure.
           */
          try {
            String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
            if (errorMessage != null && errorMessage.length() > 0) {
              ex = new JedisConnectionException(errorMessage, ex.getCause());
            }
          } catch (Exception e) {
            /*
             * Catch any IOException or JedisConnectionException occurred from InputStream#read and just
             * ignore. This approach is safe because reading error message is optional and connection
             * will eventually be closed.
             */
          }
          // Any other exceptions related to connection?
          broken = true;
          throw ex;
        }
    }

    最后我们就可以通过client.getBulkReply()的方法得到响应的数据并做处理返回。

    private static Object process(final RedisInputStream is) {
    
        final byte b = is.readByte();
        if (b == PLUS_BYTE) {
          return processStatusCodeReply(is);
        } else if (b == DOLLAR_BYTE) {
          return processBulkReply(is);
        } else if (b == ASTERISK_BYTE) {
          return processMultiBulkReply(is);
        } else if (b == COLON_BYTE) {
          return processInteger(is);
        } else if (b == MINUS_BYTE) {
          processError(is);
          return null;
        } else {
          throw new JedisConnectionException("Unknown reply: " + (char) b);
        }
    }

    其实这个方法针对于返回的数据相应做了处理的,在我们RedisTest的测试中。返回的数据是$4 huhx。这里经过process方法的处理,只会返回huhx的数据。具体的这里不作分析。

    友情链接

  • 相关阅读:
    Python: execute an external program (zz)
    Python notes
    Web Monitor/Dev/Test Tool Collection 网站/网页监控/开发/测试工具集合
    SilkTest 2006 sp2 Notes of GettingStartedTutorial (2008,07)
    Software Testing Essentials 软件测试精要
    Flex notes
    Review Java advanced features
    Fedora 11 Configuration and Management
    进制转换的方法原理
    win32 透明置顶
  • 原文地址:https://www.cnblogs.com/huhx/p/baseuseredis1.html
Copyright © 2011-2022 走看看