## Architecture
Redis is the chosen database technology and the final product will deploy autonomous
-redis cluster. In R0 schedule, single, non-redundant, non-persistent redis server is
-deployed
+redis cluster. Supported deployment options are standalone Redis server and HA
+(Sentinel) Redis deployment. Either deployment option won't provide data persistency.
## Subsystem structure
### DBaaS service
-In R0, dbaas service is realized with single container running redis database.
-The database is configured to be non-persistent and non-redundant. The container
-exposes single port which is hardcoded to be 6379.
+Dbaas service is realized either with single container running redis database
+or with HA deployment implemented by a redis sentinel solution.
+Standalone dbaas database is configured to be non-persistent and
+non-redundant. HA dbaas provides redundancy but it is also configured to be
+non-persistent.
After dbaas service is installed, environment variables **DBAAS_SERVICE_HOST**
-and **DBAAS_SERVICE_PORT** are exposed to application containers. SDL library
-will automatically use these environment variables.
+and **DBAAS_SERVICE_PORT** are exposed to application containers. In the case
+of HA dbaas deployment environment variables **DBAAS_MASTER_NAME** and
+**DBAAS_SERVICE_SENTINEL_PORT** are also exposed to application containers.
+SDL library will automatically use these environment variables.
The service is installed via helm by using dbaas-service chart. Modify the
values accordingly before installation (repository location, image name, ..)
package sdl
import (
+ "fmt"
"github.com/go-redis/redis"
"os"
"reflect"
nsPrefix: "{" + nameSpace + "},",
client: client,
}
+ s.CheckRedisModuleExtensionCommands()
return &s
}
+func (s *SdlInstance) CheckRedisModuleExtensionCommands() {
+ var moduleError bool
+ commands, err := s.client.Command(s.client.Context()).Result()
+ if err == nil {
+ redisModuleCommands := []string{
+ "setie", "delie", "setiepub", "setnxpub",
+ "msetmpub", "delmpub",
+ }
+ for _, v := range redisModuleCommands {
+ _, ok := commands[v]
+ if !ok {
+ fmt.Println("ERROR: Missing command:", v)
+ moduleError = true
+ }
+ }
+ } else {
+ fmt.Println("ERROR:", err)
+ }
+ if moduleError {
+ fmt.Println("Please make sure that redis extension modules have been installed.")
+ fmt.Println("To install: redis-cli module load /usr/local/libexec/redismodule/libredismodule.so")
+ }
+}
+
func (s *SdlInstance) setNamespaceToKeys(pairs ...interface{}) []interface{} {
var retVal []interface{}
for i, v := range pairs {
func (s *SdlInstance) Set(pairs ...interface{}) error {
keyAndData := s.setNamespaceToKeys(pairs...)
- err := s.client.MSet(keyAndData...).Err()
+ err := s.client.MSet(s.client.Context(), keyAndData...).Err()
return err
}
for _, v := range keys {
keysWithNs = append(keysWithNs, s.nsPrefix+v)
}
- val, err := s.client.MGet(keysWithNs...).Result()
+ val, err := s.client.MGet(s.client.Context(), keysWithNs...).Result()
m := make(map[string]interface{})
if err != nil {
return m, err
func (s *SdlInstance) RemoveAll() {
panic("RemoveAll not implemented\n")
}
-
package main
import (
- "fmt"
- "./sdl"
+ "./sdl"
+ "fmt"
)
func main() {
- sdl1 := sdl.Create("test1")
+ sdl1 := sdl.Create("test1")
- var err error
+ var err error
- err = sdl1.Set("key1", "data1", "key2", "data2")
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ err = sdl1.Set("key1", "data1", "key2", "data2")
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- err = sdl1.Set("num1", 1, "num2", 2)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ err = sdl1.Set("num1", 1, "num2", 2)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- d := make([]byte, 3)
- d[0] = 1
- d[1] = 2
- d[2] = 3
- err = sdl1.Set("arr1", d)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ d := make([]byte, 3)
+ d[0] = 1
+ d[1] = 2
+ d[2] = 3
+ err = sdl1.Set("arr1", d)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- p := []string{"pair1", "data1", "pair2", "data2"}
- err = sdl1.Set(p)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ p := []string{"pair1", "data1", "pair2", "data2"}
+ err = sdl1.Set(p)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- a := [4]string{"array1", "adata1", "array2", "adata2"}
- err = sdl1.Set(a)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ a := [4]string{"array1", "adata1", "array2", "adata2"}
+ err = sdl1.Set(a)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- mix1 := []interface{}{"mix1", "data1", "mix2", 2}
- err = sdl1.Set(mix1)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ mix1 := []interface{}{"mix1", "data1", "mix2", 2}
+ err = sdl1.Set(mix1)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- mix2 := [4]interface{}{"mix3", "data3", "mix4", 4}
- err = sdl1.Set(mix2)
- if err != nil {
- fmt.Printf("unable to write to DB\n")
- }
+ mix2 := [4]interface{}{"mix3", "data3", "mix4", 4}
+ err = sdl1.Set(mix2)
+ if err != nil {
+ fmt.Printf("unable to write to DB\n")
+ }
- retDataMap, err := sdl1.Get([]string{"key1", "key3", "key2"})
- if err != nil {
- fmt.Printf("Unable to read from DB\n")
- } else {
- for i, v := range retDataMap {
- fmt.Printf("%s:%s\n", i, v)
- }
- }
+ retDataMap, err := sdl1.Get([]string{"key1", "key3", "key2"})
+ if err != nil {
+ fmt.Printf("Unable to read from DB\n")
+ } else {
+ for i, v := range retDataMap {
+ fmt.Printf("%s:%s\n", i, v)
+ }
+ }
- retDataMap2, err := sdl1.Get([]string{"num1", "num2"})
- if err != nil {
- fmt.Printf("Unable to read from DB\n")
- } else {
- for i, v := range retDataMap2 {
- fmt.Printf("%s:%s\n", i, v)
- }
- }
+ retDataMap2, err := sdl1.Get([]string{"num1", "num2"})
+ if err != nil {
+ fmt.Printf("Unable to read from DB\n")
+ } else {
+ for i, v := range retDataMap2 {
+ fmt.Printf("%s:%s\n", i, v)
+ }
+ }
- fmt.Println("-------------")
- allKeys := []string{"key1", "key2", "num1", "num2", "pair1", "pair2", "array1", "array2", "mix1", "mix2", "mix3", "mix4", "arr1"}
- retDataMap3, err := sdl1.Get(allKeys)
- if err != nil {
- fmt.Printf("Unable to read from DB\n")
- } else {
- for i3, v3 := range retDataMap3 {
- fmt.Printf("%s:%s\n", i3, v3)
- }
- }
+ fmt.Println("-------------")
+ allKeys := []string{"key1", "key2", "num1", "num2", "pair1", "pair2", "array1", "array2", "mix1", "mix2", "mix3", "mix4", "arr1"}
+ retDataMap3, err := sdl1.Get(allKeys)
+ if err != nil {
+ fmt.Printf("Unable to read from DB\n")
+ } else {
+ for i3, v3 := range retDataMap3 {
+ fmt.Printf("%s:%s\n", i3, v3)
+ }
+ }
}