Redis Mass Insertion HSET command

635 views Asked by At

I have been looking all over SO for a working solution but no luck :/

I want to perform the mass insertion using the pipelining feature of redis-cli but I am not able to do so.

I have a JAVA code snippet which create a file containing all the commands to run.

      String add = "*4\r\n$4\r\nHSET\r\n$22\r\ndiscountProgramOffers\r\n$" +
            key.getBytes().length + "\r\n" + key + "\r\n$" +
            json.getBytes().length + "\r\n" + json + "\r\n";

            System.out.println(add);

In the above code, I followed mass insertion link present at Redis Documentation site.

And this is a demo String which is getting created.

*4\r\n$4\r\nHSET\r\n$22\r\ndiscountProgramOffers\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n

When I run the file which is created by the snippet, sometimes I get nothing, and sometimes I get this error:

Error writing to the server: Connection reset by peer

EX:

echo -e "$(cat  massInsert.txt)" | redis/src/redis-cli --pipe
Error writing to the server: Connection reset by peer

Am I doing something wrong?? Please help.

FYI: I referred to these questions:

  1. Redis Mass Insertion
  2. redis - mass inserts and counters
2

There are 2 answers

0
mirekphd On

If you are doing everything right, but it still does not work, it may be your linux shell's fault and you may need to switch the shell (e.g. to BusyBox ash on Alpine, where Redis is usually conveniently installed, at least in containerized versions).

Correctly formed RESP strings should display in full (i.e. with each keyword and key or value name in separate line) when using either of these commands:

$ printf $(cat redis-cmd-tst.txt)
*1
$4
HSET
$21
discountProgramOffers
$6
mykey1
$8
myvalue1

$ echo -e $(cat /tmp/tst/redis-cmd-tst.txt)
*1
$4
HSET
$21
discountProgramOffers
$6
mykey1
$8
myvalue1

Currently I've verified it works either in BusyBox ash (linked to /bin/sh) on Alpine:

$ echo $0
/bin/ash

$ /bin/ash --help
BusyBox v1.35.0 (2022-08-01 15:14:44 UTC) multi-call binary.

Usage: ash [-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]

Unix shell interpreter

$ cat /etc/os-release 
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.16.2
PRETTY_NAME="Alpine Linux v3.16"

... while it fails to print correctly RESP files in either shell preinstalled on Ubuntu (so both in bash and in dash, to which sh is linked on Ubuntu):

$ printf $(cat dict-to-redis-working.txt)
$ echo -e $(cat dict-to-redis-working.txt)
 31T3

$ echo $0
/bin/dash

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
UBUNTU_CODENAME=focal
0
mirekphd On

Looks like a simple off-by-one error in creating the RESP protocol string:) There are 21, not 22 characters in the discountProgramOffers hash name.

It worked for me (also with printf instead of echo -e), but only in Alpine's shell ash (see the other answer for details):


# inspect data
$ cat redis-cmd-tst.txt 
*4\r\n$4\r\nHSET\r\n$21\r\ndiscountProgramOffers\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n

# transfer
$ echo -e $(cat redis-cmd-tst.txt) | redis-cli --pipe -a $REDIS_PASSWORD
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1

# verify
$ redis-cli -a $REDIS_PASSWORD hget discountProgramOffers mykey
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"myvalue"