0

I am new to Redis and developing code using Spring Boot + Spring Data Redis example. When I saved the records, I see KEYS gets created and out of these keys 4 are HASH, 1 ZSET and all others are SET.

I did not see in the Spring docs, meaning of each KEY is getting saved. .

127.0.0.1:6379> KEYS *
 1) "persons:c5cfd49d-6688-4b83-a9b7-be55dd1c36ad"
 2) "persons:firstname:bran"
 3) "persons:39e14dae-fa23-4935-948f-1922d668d1c2"
 4) "persons:f0b6dd26-8922-4a36-bd2a-792a17dddff7"
 5) "persons:address.city:Achalpur"
 6) "persons:e493385a-64ae-42be-8398-51757153d273:idx"
 7) "persons:053cdfea-e430-4e1c-acbd-ac40050b10cd:idx"
 8) "persons:firstname:rickon"
 9) "persons:e493385a-64ae-42be-8398-51757153d273"
10) "persons:address.country:India"
11) "persons:e7fc3ebe-9b48-48a8-a5f4-33a0e21f782f:idx"
12) "persons:firstname:sansa"
13) "persons:address:location"
14) "persons:firstname:robb"
15) "persons:firstname:jon"
16) "persons:lastname:snow"
17) "persons:e7fc3ebe-9b48-48a8-a5f4-33a0e21f782f"
18) "persons:c5cfd49d-6688-4b83-a9b7-be55dd1c36ad:idx"
19) "persons:lastname:stark"
20) "persons:f0b6dd26-8922-4a36-bd2a-792a17dddff7:idx"
21) "persons:053cdfea-e430-4e1c-acbd-ac40050b10cd"
22) "persons:39e14dae-fa23-4935-948f-1922d668d1c2:idx"
23) "persons:firstname:arya"
24) "persons:83cd4f58-c272-4d81-9023-8c66c8ac34b0:idx"
25) "persons:83cd4f58-c272-4d81-9023-8c66c8ac34b0"
26) "persons:address.city:Nagpur"
27) "persons:firstname:eddard"
28) "persons"

enter image description here

Person.java

@Data
@EqualsAndHashCode(exclude = { "children" })
@NoArgsConstructor
@AllArgsConstructor
@Builder
@RedisHash("persons")
public class Person {

    private @Id String id;
    private @Indexed String firstname;
    private @Indexed String lastname;

    private Gender gender;
    private Address address;

    private @Reference List<Person> children;
}

Address.java

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Address {

    private @Indexed String city;
    private @Indexed String country;
    private @GeoIndexed Point location;
}

Gender.java

public enum Gender {
    FEMALE, MALE
}

RedisExampleBootApplication.java

@SpringBootApplication
public class RedisExampleBootApplication implements CommandLineRunner{

    @Autowired PersonRepository repository;

    public static void main(String[] args) {
        SpringApplication.run(RedisExampleBootApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {  
        Address address1 = Address.builder().city("the north").country("winterfell").location(new Point(52.9541053, -1.2401016)).build();
        Address address2 = Address.builder().city("Casterlystein").country("Westerland").location(new Point(51.5287352, -0.3817819)).build();

        Person eddard = Person.builder().firstname("eddard").lastname("stark").gender(Gender.MALE).address(address1).build();
        Person robb = Person.builder().firstname("robb").lastname("stark").gender(Gender.MALE).address(address2).build();
        Person sansa = Person.builder().firstname("sansa").lastname("stark").gender(Gender.FEMALE).address(address1).build();
        Person arya = Person.builder().firstname("arya").lastname("stark").gender(Gender.FEMALE).address(address2).build();
        Person bran = Person.builder().firstname("bran").lastname("stark").gender(Gender.MALE).address(address1).build();
        Person rickon = Person.builder().firstname("rickon").lastname("stark").gender(Gender.MALE).address(address2).build();
        Person jon = Person.builder().firstname("jon").lastname("snow").gender(Gender.MALE).address(address1).build();

        repository.save(eddard);
        repository.save(robb);
        repository.save(sansa);
        repository.save(arya);
        repository.save(bran);
        repository.save(rickon);
        repository.save(jon);

        List<Person> starks = repository.findByLastname(eddard.getLastname());
        System.out.println("Person ="+starks.size());
    }
}
PAA
  • 1
  • 46
  • 174
  • 282

1 Answers1

1

Before answering, do you mind sharing your RedisTemplate implementation code? (Or this is generated by @RedisHash annotation?) I am new to Spring-Data-Redis myself and didn't know of the @RedisHash annotation and want to check it out.

Anyways, essentially what is happening here is that Spring-Data-Redis repository is inserting the Person object in different data structures natively supported by Redis for different purposes.

Redis supports different data structures such as:

  1. Hash Redis creates a map of string fields and string values to represent your entire Person object. If you do HGETALL persons:{your person id} it will show all the different fields and values associated with your person Object

    HASH holding property values for id "c5cfd49d-6688-4b83-a9b7-be55dd1c36ad" in keyspace "persons"

  2. Set Redis inserts the basic raw string and indexes entities based on their field. Hence there were a lot SET operations in your Redis DB. You can see indexes of firstName and lastName in your data set

    SET holding all ids known in the keyspace "persons"

  3. ZSet This is Redis operation for Sorted Sets data structure. Which is an ordered collections of strings. From Redis Documentations

    In short with sorted sets you can do a lot of tasks with great performance that are really hard to model in other kind of databases.

Seems like Spring Data automatically inserts the location data as a sorted set to optimize CRUD operations.

You can read more here:

https://github.com/spring-projects/spring-data-examples/blob/master/redis/repositories/README.md

https://redis.io/topics/data-types

JWiryo
  • 371
  • 4
  • 11
  • Hi thank you for posting. I have better idea for my own code improvements now. Sorry, but I thought your question was why did the CrudRepository performed a lot of different kind of insertion operations? Maybe If i have better understanding of your concern I can modify the answer? Thank you – JWiryo Nov 08 '18 at 09:49
  • This is also part of my concern - "why did the CrudRepository performed a lot of different kind of insertion operations?" – PAA Nov 08 '18 at 09:51
  • 1
    Ah I see... Essentially, Spring-Data-Redis does a lot of optimization to ensure that the CRUD operation can be done quickly. In this case, because you added `@Indexed` annotation to your Person fields, it automatically does `SET` commands to do secondary indexing. I believe that if your class is very simple no other annotations attached to it. The repository will not do as much operations but probably only does `HSET` to insert the data into redis.. You can see that you used a lot of `@indexed` and `@GeoIndexed`. These forces the repository to do more operations for you – JWiryo Nov 08 '18 at 09:55
  • Ok Thanks. I just wanted to ask generic question. I am looking to move Postgres to Redis - I almost have static data around 5K records only. But while converting JPA to Redis Entity, I am not sure how to maintain the Many-To-Many - bi-directional with join table and Many-To-One relationship ? I simply thought of removing all annotations and keep the POJO as simple as possible. Now How to take care of join-table. Could you please let me know how to model data and how to learn more about redis? I dont see good material over web – PAA Nov 08 '18 at 09:58
  • Also, how to make the use of `@Reference`, because same private `@Reference List children;` object use in the same Person class – PAA Nov 08 '18 at 10:04
  • With regards to moving Data from Postgres to Redis. I think its not the right choice of system. Redis has no relational relationship between the data. In essence, you can't do complex queries with JOIN and all that. Redis is most popular to use as Cache or simple temporary data storage before moving the data permanently into a Relational or NoSQL DB. And with regards to `@Reference`. https://docs.oasis-open.org/opencsa/sca-j/javadoc/org/oasisopen/sca/annotation/Reference.html Can look more into this – JWiryo Nov 08 '18 at 10:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183287/discussion-between-paa-and-jwiryo). – PAA Nov 08 '18 at 10:14