《Learning Redis》学习笔记一:基础介绍

本文是《Learning Redis》的学习笔记,介绍了Redis的基础知识,包括Redis的快速安装与启动、客户端连接、主要数据类型及操作命令,以及通信协议RESP。Redis作为NoSql数据库,以其高速的key-value存储和丰富的数据类型支持,广泛应用于数据存储和缓存场景。
摘要由CSDN通过智能技术生成

Redis是面向key-value存储速度最快的NoSql数据库之一,既可基于内存也可持久化。作为key-value数据存储,在一些非功能性需求中主要有以下特点:

1、数据集插入快,无异常

2、随机读:所有keys放内存因此读取速度非常快,Redis使用虚拟内存将keys存内存,将最小最近使用的values放磁盘来避免内存消耗

3、容错性和负载均衡:采用主从拓扑结构,master-slave;读请求均匀分布于从节点;

4、最终一致性:主节点更新从节点也会异步更新,存在短暂时间点不一致问题但会到达最终一致

5、分片和可扩展性:节点水平扩展使得数据集能大于内存

6、多数据中心支持+可管理+多客户端

一、Redis的安装和启动

1、下载zip安装文件解压即可

2、在redis安装目录下,直接运行Redis-server.exe或者Windows命令redis-server [redis.windows.conf]启动,默认端口号6379

3、conf文件是redis配置文件可以重名名和修改默认属性,修改后启动必需带上配置文件参数,否则还是以默认参数启动

二、客户端连接

1、进入redis安装目录,执行cmd命令:redis-cli [-h] [-p] 默认配置下IP和端口可以省略,可以连接多个客户端

2、连接客户端可进行各种数据操作,redis主要支持5种数据类型:String/List/Set/SortedSet/Hashes

3、基本命令:set/get等,不同数据类型set/get命令有不同前缀,可查询相关文档了解

例如String类型:set/get key [value]基本存取值操作;setNx N一般代表已存在key不做操作,不存在则新建;setEx E代表附加失效操作,单位秒set key value ex timeout

以下示例是几种数据类型在java中的简单使用,在以Redis作为数据库的时候会用到:

public class TestJedis {

    private JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "localhost");

    private Jedis jedis;

    public Jedis getResource() {
        jedis = jedisPool.getResource();
        return jedis;
    }

    public void setResource() {
        jedis.close();
    }

    /**
     * redis sets类型基本操作
     */
    private void testSetsType() {
        Jedis jedis = getResource();
        jedis.sadd("follow:cricket", "vinoo.das@junk-mail.com", "vinoo.das1@junk-mail.com",
            "vinoo.das3@junk-mail.com");
        System.out.println("follow:cricket" + " : " + jedis.smembers("follow:cricket"));
        //元素个数统计
        Assert.assertEquals(3, jedis.scard("follow:cricket").longValue());
        jedis.sadd("follow:redis", "vinoo.das1@junk-mail.com", "vinoo.das2@junk-mail.com");
        System.out.println("follow:redis" + " : " + jedis.smembers("follow:redis"));
        Assert.assertEquals(2 , jedis.scard("follow:redis").longValue());

        //获取集合中的公共元素
        System.out.println(jedis.sinter("Cricket:followers", "follow:redis"));
        //存储集合中的公共元素到指定list中
        jedis.sinterstore("follow:redis+cricket", "follow:cricket", "follow:redis");
        System.out.println("follow:redis+cricket" + " : " + jedis.smembers("follow:redis+cricket"));
        System.out.println(jedis.sismember("follow:redis+cricket", "vinoo.das@junk-mail.com"));
        System.out.println(jedis.sismember("follow:redis+cricket", "vinoo.das1@junk-mail.com"));

        //将成员从源集合移到目标集合中,但源集合中不删除该成员
        jedis.smove("follow:cricket", "follow:redis", "vinoo.das3@junkmail.com");
        System.out.println("follow:cricket" + " : " + jedis.smembers("follow:cricket"));
        System.out.println("follow:redis" + " : " + jedis.smembers("follow:redis"));
        //随机返回一个元素
        System.out.println(jedis.srandmember("follow:cricket"));
        //随机移除
        System.out.println(jedis.spop("follow:cricket"));
        System.out.println(jedis.smembers("follow:cricket"));
        jedis.sadd("follow:cricket","wrong-data@junk-mail.com");
        System.out.println(jedis.smembers("follow:cricket"));
        jedis.srem("follow:cricket","wrong-data@junk-mail.com");
        System.out.println(jedis.smembers("follow:cricket"));
        System.out.println(jedis.sunion("follow:cricket", "follow:redis"));
        jedis.sunionstore("follow:cricket-or-redis", "follow:cricket", "follow:redis");
        System.out.println("follow:cricket-or-redis" + " : " + jedis.smembers("follow:cricket-or-redis"));
        System.out.println(jedis.sdiff("follow:cricket", "follow:redis"));
    }

    /**
     * redis List类型基本操作
     */
    private void testListType() {
        Jedis jedis = getResource();
        String key1 = "mykey4list1";
        String key2 = "mykey4list2";
        System.out.println("del key : " + jedis.del(key1, key2).longValue());

        for (int i = 0; i < 3; i++) {
            jedis.lpush(key1, "message" + i);
        }
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        for (int i = 3; i < 6; i++) {
            jedis.rpush(key2, "message" + i);
        }
        System.out.println(key2 + ":" + jedis.lrange(key2, 0, -1));

        Assert.assertEquals("message2", jedis.lindex(key1, 0));

        System.out.println(jedis.linsert(key1, LIST_POSITION.AFTER, "message2", "message7"));
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        Assert.assertEquals(4, jedis.llen(key1).longValue());
        //从左边移除第一个元素
        System.out.println("remove : " + jedis.lpop(key1));
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));

        System.out.println(jedis.lpushx(key1, "Message - 1.8"));
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        //按顺序和个数移除指定值,负数从右到左,0移除全部指定元素
        System.out.println(jedis.lrem(key1, 0, "Message - 1.8"));
        System.out.println(jedis.lrange(key1, 0, -1));

        System.out.println(jedis.lset(key1, -1, "Message - 7"));
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        System.out.println(jedis.ltrim(key1, 0, -1));
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        //最右边的元素从list1移到list2中
        jedis.rpoplpush(key1, key2);
        System.out.println(key1 + ":" + jedis.lrange(key1, 0, -1));
        System.out.println(key2 + ":" + jedis.lrange(key2, 0, -1));
    }

    /**
     * redis hashes类型基本操作
     */
    private void testHashesType() {
        Jedis jedis = getResource();
        String commonkey = "learning redis";
        jedis.hset(commonkey, "publisher", "Packt Publisher");
        jedis.hset(commonkey, "author", "Vinoo Das");
        System.out.println(jedis.hgetAll(commonkey).get("author"));
        Map<String, String> attributes = new HashMap<>();
        attributes.put("ISBN", "XX-XX-XX-XX");
        attributes.put("tags", "Redis,NoSQL");
        attributes.put("pages", "250");
        attributes.put("weight", "200.56");
        jedis.hmset(commonkey, attributes);
        System.out.println(jedis.hgetAll(commonkey));
        System.out.println(jedis.hget(commonkey, "publisher"));
        System.out.println(jedis.hmget(commonkey, "publisher", "author"));
        System.out.println(jedis.hvals(commonkey));
        System.out.println(jedis.hget(commonkey, "publisher"));
        System.out.println(jedis.hkeys(commonkey));
        System.out.println(jedis.hexists(commonkey, "cost"));
        System.out.println(jedis.hlen(commonkey));
        System.out.println(jedis.hincrBy(commonkey, "pages", 10));
        System.out.println(jedis.hincrByFloat(commonkey, "weight", 1.1) + "gms");
        System.out.println(jedis.hdel(commonkey, "weight-in-gms"));
        System.out.println(jedis.hgetAll(commonkey));
        setResource();
    }
}
4、在客户端查看所有keys命令: keys * ,也支持通配表达式keys pattern

5、删除key:del key 删除该库所有key:flushDb  删除所有库所有数据:flushall

6、其它一些常用命令:

->append key value 追加值

->strlen key  查看value长度

->setRange key offset value 从offset位置开始替换或插入值,原长度不够的前置补'\xoo'

三、通信协议RESP(Redis Serialization Protocol)

Redis工作于C-S模式,客户端和服务端之前使用TCP/IP协议(应用层、传输层、网络层、网关接口),client向server发送请求数据包括:请求主体(Request Data)和请求头header(meta info),server向client返回数据包括:响应主体(Response Data)和响应头header;Header+Body共同构成信息块用于传输数据,Header主要包括协议名称、版本号、安全信息、参数个数和类型等,body存放的主要是真实数据。

以下是一个简单的使用实例:

抽象类Command主要是建立连接和定义通用命令执行方法:

public abstract class Command {

    protected Socket socket;

    public Command() {
        try {
            socket = new Socket(ConnectionProperties.host, ConnectionProperties.port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String createPayload(ArrayList<String> messageList) {
        int argumentSize = messageList.size();
        StringBuffer payload = new StringBuffer();
        payload.append('*');
        payload.append(argumentSize);
        payload.append("\r\n");
        for (int cursor = 0; cursor < messageList.size(); cursor++) {
            payload.append("$");
            payload.append(messageList.get(cursor).length());
            payload.append("\r\n");
            payload.append(messageList.get(cursor));
            payload.append("\r\n");
        }
        return payload.toString().trim();
    }

    public abstract String createPayload();

    public abstract void execute() throws IOException;

接下来是set/get命令执行,SetCommand和GetCommand继承抽象类Command:

public class SetCommand extends Command {

    private String key;
    private String value;

    public SetCommand(String key, String value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public String createPayload() {
        ArrayList<String> messageList = new ArrayList<>();
        messageList.add("SET");
        messageList.add(key);
        messageList.add(value);
        return super.createPayload(messageList);
    }

    @Override
    public void execute() throws IOException {
        PrintWriter out = null;
        BufferedReader in = null;
        try {
            out = new PrintWriter(super.socket.getOutputStream(), true);
            out.println(createPayload());
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(in.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            in.close();
            out.flush();
            out.close();
            socket.close();
        }
    }
}
public class GetCommand extends Command {

    private String key;

    public GetCommand(String key) {
        this.key = key;
    }

    @Override
    public String createPayload() {
        ArrayList<String> messageList = new ArrayList<>();
        messageList.add("GET");
        messageList.add(key);
        return super.createPayload(messageList);
    }

    @Override
    public void execute() throws IOException {
        PrintWriter out = null;
        BufferedReader in = null;
        try {
            out = new PrintWriter(super.socket.getOutputStream(), true);
            out.println(this.createPayload());
            //Reads from Redis server
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String msg = in.readLine();
            if (!msg.contains("-1")) {
                System.out.println(msg);
                System.out.println(in.readLine());
            } else {
                // This will show the error message since the
                // server has returned '-1'
                System.out.println("This Key does not exist !");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
            in.close();
            socket.close();
        }
    }
}
测试类如下:

public class TestClient {

    public void execute(Command command) {
        try {
            command.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        TestClient testClient = new TestClient();
        SetCommand setCommand = new SetCommand("msg", "redis learning");
        testClient.execute(setCommand);

        GetCommand getCommand = new GetCommand("msg");
        testClient.execute(getCommand);
    }
}



About This Book Model and design databases effectively in Redis Learn about sharding, indexing, and migrating strategies in Redis A simple step-by-step tutorial explaining the main concepts of Redis through practical examples Who This Book Is For This book is for SQL developers who want to learn about Redis, the key value database for scalability and performance. Prior understanding of a programming language is essential; however no knowledge of NoSQL is required. What You Will Learn Familiarise yourself with NoSQL and install Redis Build solutions and enhance your web applications in Redis Understand the persistent mechanism for better scalability Configure and tune the server to improve performance Identify bottlenecks and how to handle fault management in Redis Learn about backups and recovery strategies for the Redis environment Discover the commands and functions of Redis In Detail This book will introduce Redis and help you understand its various facets. Starting with an introduction to NoSQL, you will learn how to install Redis and how to classify and work with data structures. By working with real world scenarios pertaining to using Redis, you will discover sharding and indexing techniques, along with how to improve scalability and performance through persistent strategies and data migration techniques. With the help of multiple examples, you will learn to design web and business applications. You will also learn how to configure Redis for setting up clusters and tuning it for performance. At the end of this book, you will find essential tips on backup and recovery strategies for the Redis environment.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值