Este post indica como instalar un cluster de cassandra con mas de un nodo. Asumo que la máquina en donde se va a instalar es un Ubuntu 16.04 obtenido de AWS:

sudo sh -c "echo 'LC_ALL=en_US.UTF-8\nLANG=en_US.UTF-8' >> /etc/environment"
sudo apt-get update
sudo apt-get install python2.7
sudo apt-get install default-jdk
    
sudo groupadd cassandra
sudo useradd -d /home/cassandra -s /bin/bash -m -g cassandra cassandra
sudo su cassandra -l
wget http://www-eu.apache.org/dist/cassandra/3.9/apache-cassandra-3.9-bin.tar.gz
tar -xzvf apache-cassandra-3.9-bin.tar.gz
nano apache-cassandra-3.9/conf/cassandra-env.sh
nano apache-cassandra-3.9/conf/cassandra.yaml

Posterior a los 11 comandos anteriores, hay que editar el archivo:

CASSANDRA_HOME/conf/cassandra.yaml

los cambios son los siguientes:

. . .
cluster_name: 'GooseDOCluster'
. . .
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
         - seeds: "your_server_ip,your_server_ip_2,...your_server_ip_n"
. . .
listen_address: your_server_ip
. . .
rpc_address: your_server_ip
. . .
endpoint_snitch: GossipingPropertyFileSnitch
. . .

Yo puse las IP’s internas en cada : “your_server_ip” porque las externas (o públicas) no me funcionaron.
Ahora hay que reiniciar el servicio. Todos los binarios se encuentran en CASSANDRA_HOME/bin

Si llegara a haber algún problema de conexión, se tendrá que editar el archivo cassandra-env.sh reemplazando el hostname por el IP interno de la máquina:

JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=[host_name]"

Listo !!!

Desde una máquina cliente hacer:

%> ssh -p 10822 ejemplo@acme.org.mx -L 3307:localhost:3306 -N -f

Ahora desde la misma máquina hacer:

%> mysql -h 127.0.0.1 -u fulanito -p -P 3307

Y listo !!!!!!!!!

Cheers,
Goose

Pues si. Como instalé un servidor LAMP, no sabía que no es suficiente con el típico:

sudo iptables -A INPUT -i eth0 -s 10.5.1.3 -p tcp --destination-port 3306 -j ACCEPT

Además hay que cambiar el archivo my.cnf y comentar la linea que dice:

skip-networking

Debe estar comentada ! (y en vez de 127.0.0.1 poner la IP de nuestro servidor)

Por último, reiniciar el servicio de mysql:

sudo /etc/init.d/mysql restart

Obviamente ya dimos permisos de acceso remoto a algunos usuarios con grant all priv…. verdad?

Cheers,
Goose

En el trabajo diario como desarrollador de aplicaciones, es común llegar a necesitar extender la funcionalidad existente en tu manejador de bases de datos para que en tus cadenas sql puedas usar tal funcionalidad como si fuera nativa del manejador.

Me explico mejor con un ejemplo: Supongamos que requiero calcular la “distancia” entre dos palabras con la métrica de levenshtein y esto deseo calcularlo para cada túpla en mi tabla “Personas” aplicado a los atributos apPat y apMat. Mi cadena sql luciría mas o menos así:

SELECT id, apPat, apMat, levenshtein(apPat, apMat) as distancia FROM Personas;

Arrojando un resultado como el siguiente:

+—-+———+———-+———–+

| id | apPat   | apMat    | distancia |

+—-+———+———-+———–+

| 1 | Arellano | Arellani | 1         |

| 2 | Arevalo  | Orevale  | 2         |

| 3 | Benitez  | Venitez  | 2         |

| 4 | Cardona  | Cardona  | 0         |

| 5 | Corona   | Lopez    | 6         |

+—-+———+———-+———–+

5 rows in set (0.07 sec)

Pero, cómo lograrlo?

Bueno, encontré dos formas. Una fácil, pero con cierto castigo en el desempeño de la ejecución de la consulta. Y uno difícil (y que NO sé cómo llevar a cabo en Windows, sólo lo efectué en LINUX) pero con un desempeño excelente.

Primero, el primero:

Desde tu consola de MySQL y habiendo ya creado y seleccionado la base de datos ( y la tabla “Personas” con algunos datos de prueba) llevar a cabo lo siguiente:

mysql> delimiter //

mysql> CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
  RETURNS INT
  DETERMINISTIC
  BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR;
    -- max strlen=255
    DECLARE cv0, cv1 VARBINARY(256);
    SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
    IF s1 = s2 THEN
      RETURN 0;
    ELSEIF s1_len = 0 THEN
      RETURN s2_len;
    ELSEIF s2_len = 0 THEN
      RETURN s1_len;
    ELSE
      WHILE j <= s2_len DO
        SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
      END WHILE;
      WHILE i <= s1_len DO
        SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
        WHILE j <= s2_len DO
          SET c = c + 1;
          IF s1_char = SUBSTRING(s2, j, 1) THEN 
            SET cost = 0; ELSE SET cost = 1;
          END IF;
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
          IF c > c_temp THEN SET c = c_temp; END IF;
            SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
            IF c > c_temp THEN 
              SET c = c_temp; 
            END IF;
            SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
        END WHILE;
        SET cv1 = cv0, i = i + 1;
      END WHILE;
    END IF;
    RETURN c;
  END;

//

 

 

mysql> delimiter ;

Ahora ya podemos ejecutar el query que mencionaba originalmente, obteniendo el resultado descrito, y hasta queries como:

SELECT * from Personas where levenshtein(apPat, apMat)<2;

PARTE II

La forma “difícil” es usando C, compilando el código ya declarándolo en mySQL. Va más o menos así:

Con el código en C (que puedes obtener del tar de la liga siguiente, o puedes pedírmelo y lo desempolvo de mi privado/software/tars ) hice lo siguiente:

%> sudo yum install mysqld gcc-c++

%> wget http://joshdrew.com/mysql_levenshtein_udf-1.0.tar.gz

%> tar zxf mysql_levenshtein_udf-1.0.tar.gz

%> gcc -shared -o mysqllevenshtein.so mysqllevenshtein.cc -I/usr/include/mysql/

%> sudo cp mysqllevenshtein.so /usr/lib/

y en MySQL:

mysql> use miBaseDeDatos;

mysql> CREATE FUNCTION levenshtein RETURNS INT SONAME ‘mysqllevenshtein.so’;

Y ya quedó. El desempeño es 100% mejor, ya que baja de 0.07 a 0.00. (La verdad, no es un 0 absoluto, pero con ello puedo ver que tardó menos de 0.00 y con eso, es suficiente para mi.)

Hasta pronto!

Goose

© 2017 Goose Workshop Suffusion theme by Sayontan Sinha